UNPKG

zod

Version:

TypeScript-first schema declaration and validation library with static type inference

1,441 lines โ€ข 91.2 kB
import { randomBytes } from "node:crypto";
import { expect, expectTypeOf, test } from "vitest";

import * as z from "zod/v4";

const minFive = z.string().min(5, "min5");
const maxFive = z.string().max(5, "max5");
const justFive = z.string().length(5);
const nonempty = z.string().min(1, "nonempty");
const includes = z.string().includes("includes");
const includesFromIndex2 = z.string().includes("includes", { position: 2 });
const startsWith = z.string().startsWith("startsWith");
const endsWith = z.string().endsWith("endsWith");

test("string factory checks", async () => {
  const schema = z.string({ checks: [z.minLength(1), z.maxLength(3)] as const });
  const chained = z.string().min(1).max(3);
  expectTypeOf<z.output<typeof schema>>().toEqualTypeOf<string>();
  for (const value of ["", "ab", "abcd", 1, undefined]) {
    expect(z.validate(schema, value)).toBe(z.validate(chained, value));
    expect(schema.safeParse(value)).toEqual(chained.safeParse(value));
  }
  expect(z.toJSONSchema(schema)).toEqual(z.toJSONSchema(chained));
  expect(schema.minLength).toBe(1);
  expect(schema.maxLength).toBe(3);
  expect(schema._zod.parent).toBeUndefined();
  expect([...schema._zod.traits]).toEqual([...chained._zod.traits]);
  const extended = schema.max(2);
  expect(extended._zod.parent).toBe(schema);
  expect(z.validate(schema, "abc")).toBe(true);
  expect(z.validate(extended, "abc")).toBe(false);
  const coerce = z.coerce.string({ checks: [z.minLength(2)] });
  expect(coerce.parse(12)).toBe("12");
  expect(z.validate(coerce, 1)).toBe(false);
  const asyncSchema = z.string({
    checks: [
      z.check<string>(async (ctx) => {
        if (ctx.value !== "ok") ctx.issues.push({ code: "custom", input: ctx.value });
      }),
    ],
  });
  expect(await asyncSchema.safeParseAsync("ok")).toEqual({ success: true, data: "ok" });
  expect((await asyncSchema.safeParseAsync("bad")).success).toBe(false);
  // @ts-expect-error numeric checks cannot validate strings
  z.string({ checks: [z.gte(1)] });
});

test("factory checks snapshot caller arrays", () => {
  for (const factory of [z.string, z.coerce.string]) {
    for (const initial of [[], [z.minLength(1)]]) {
      const schema = factory({ checks: initial });
      let reads = 0;
      const getterSchema = factory({
        get checks() {
          if (++reads > 1) throw new Error("checks read twice");
          return initial;
        },
      });
      expect(reads).toBe(1);
      expect(z.validate(getterSchema, "long")).toBe(true);
      const before = z.toJSONSchema(schema);
      initial.push(z.minLength(10));
      expect(schema._zod.def.checks).not.toBe(initial);
      expect(z.validate(schema, "long")).toBe(true);
      expect(z.validate(z.compile(schema), "long")).toBe(true);
      expect(z.toJSONSchema(schema)).toEqual(before);
      expect(z.validate(schema.check(z.minLength(2)), "long")).toBe(true);
    }
  }
});

test("length checks", () => {
  minFive.parse("12345");
  minFive.parse("123456");
  maxFive.parse("12345");
  maxFive.parse("1234");
  nonempty.parse("1");
  justFive.parse("12345");

  expect(() => minFive.parse("1234")).toThrow();
  expect(() => maxFive.parse("123456")).toThrow();
  expect(() => nonempty.parse("")).toThrow();
  expect(() => justFive.parse("1234")).toThrow();
  expect(() => justFive.parse("123456")).toThrow();
});

test("includes", () => {
  includes.parse("XincludesXX");
  includesFromIndex2.parse("XXXincludesXX");

  expect(() => includes.parse("XincludeXX")).toThrow();
  expect(() => includesFromIndex2.parse("XincludesXX")).toThrow();
});

test("includes with string error message", () => {
  const schema = z.string().includes("test", "must contain test");
  schema.parse("this is a test");

  expect(schema.safeParse("this is invalid")).toMatchInlineSnapshot(`
    {
      "error": [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "includes",
        "includes": "test",
        "path": [],
        "message": "must contain test"
      }
    ]],
      "success": false,
    }
  `);
});

test("startswith/endswith", () => {
  startsWith.parse("startsWithX");
  endsWith.parse("XendsWith");

  expect(() => startsWith.parse("x")).toThrow();
  expect(() => endsWith.parse("x")).toThrow();
});

test("email validations", () => {
  const validEmails = [
    `email@domain.com`,
    `firstname.lastname@domain.com`,
    `email@subdomain.domain.com`,
    `firstname+lastname@domain.com`,
    `1234567890@domain.com`,
    `email@domain-one.com`,
    `_______@domain.com`,
    `email@domain.name`,
    `email@domain.co.jp`,
    `firstname-lastname@domain.com`,
    `very.common@example.com`,
    `disposable.style.email.with+symbol@example.com`,
    `other.email-with-hyphen@example.com`,
    `fully-qualified-domain@example.com`,
    `user.name+tag+sorting@example.com`,
    `x@example.com`,
    `mojojojo@asdf.example.com`,
    `example-indeed@strange-example.com`,
    `example@s.example`,
    `user-@example.org`,
    `user@my-example.com`,
    `a@b.cd`,
    `work+user@mail.com`,
    `tom@test.te-st.com`,
    `something@subdomain.domain-with-hyphens.tld`,
    `common'name@domain.com`,
    `francois@etu.inp-n7.fr`,
  ];
  const invalidEmails = [
    // no "printable characters"
    // `user%example.com@example.org`,
    // `mailhost!username@example.org`,
    // `test/test@test.com`,

    // double @
    `francois@@etu.inp-n7.fr`,
    // do not support quotes
    `"email"@domain.com`,
    `"e asdf sadf ?<>ail"@domain.com`,
    `" "@example.org`,
    `"john..doe"@example.org`,
    `"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com`,
    // do not support comma
    `a,b@domain.com`,

    // do not support IPv4
    `email@123.123.123.123`,
    `email@[123.123.123.123]`,
    `postmaster@123.123.123.123`,
    `user@[68.185.127.196]`,
    `ipv4@[85.129.96.247]`,
    `valid@[79.208.229.53]`,
    `valid@[255.255.255.255]`,
    `valid@[255.0.55.2]`,
    `valid@[255.0.55.2]`,

    // do not support ipv6
    `hgrebert0@[IPv6:4dc8:ac7:ce79:8878:1290:6098:5c50:1f25]`,
    `bshapiro4@[IPv6:3669:c709:e981:4884:59a3:75d1:166b:9ae]`,
    `jsmith@[IPv6:2001:db8::1]`,
    `postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]`,
    `postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:192.168.1.1]`,

    // microsoft test cases
    `plainaddress`,
    `#@%^%#$@#$@#.com`,
    `@domain.com`,
    `Joe Smith &lt;email@domain.com&gt;`,
    `email.domain.com`,
    `email@domain@domain.com`,
    `.email@domain.com`,
    `email.@domain.com`,
    `email..email@domain.com`,
    `ใ‚ใ„ใ†ใˆใŠ@domain.com`,
    `email@domain.com (Joe Smith)`,
    `email@domain`,
    `email@-domain.com`,
    `email@111.222.333.44444`,
    `email@domain..com`,
    `Abc.example.com`,
    `A@b@c@example.com`,
    `colin..hacks@domain.com`,
    `a"b(c)d,e:f;g<h>i[j\k]l@example.com`,
    `just"not"right@example.com`,
    `this is"not\allowed@example.com`,
    `this\ still\"not\\allowed@example.com`,

    // random
    `i_like_underscore@but_its_not_allowed_in_this_part.example.com`,
    `QA[icon]CHOCOLATE[icon]@test.com`,
    `invalid@-start.com`,
    `invalid@end.com-`,
    `a.b@c.d`,
    `invalid@[1.1.1.-1]`,
    `invalid@[68.185.127.196.55]`,
    `temp@[192.168.1]`,
    `temp@[9.18.122.]`,
    `double..point@test.com`,
    `asdad@test..com`,
    `asdad@hghg...sd...au`,
    `asdad@hghg........au`,
    `invalid@[256.2.2.48]`,
    `invalid@[256.2.2.48]`,
    `invalid@[999.465.265.1]`,
    `jkibbey4@[IPv6:82c4:19a8::70a9:2aac:557::ea69:d985:28d]`,
    `mlivesay3@[9952:143f:b4df:2179:49a1:5e82:b92e:6b6]`,
    `gbacher0@[IPv6:bc37:4d3f:5048:2e26:37cc:248e:df8e:2f7f:af]`,
    `invalid@[IPv6:5348:4ed3:5d38:67fb:e9b:acd2:c13:192.168.256.1]`,
    `test@.com`,
    `aaaaaaaaaaaaaaalongemailthatcausesregexDoSvulnerability@test.c`,
  ];
  const emailSchema = z.string().email();

  expect(
    validEmails.every((email) => {
      return emailSchema.safeParse(email).success;
    })
  ).toBe(true);
  expect(
    invalidEmails.every((email) => {
      return emailSchema.safeParse(email).success === false;
    })
  ).toBe(true);
});

test("base64 validations", () => {
  const validBase64Strings = [
    "SGVsbG8gV29ybGQ=", // "Hello World"
    "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==", // "This is an encoded string"
    "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms=", // "Many hands make light work"
    "UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // "Patience is the key to success"
    "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // "Base64 encoding is fun"
    "MTIzNDU2Nzg5MA==", // "1234567890"
    "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=", // "abcdefghijklmnopqrstuvwxyz"
    "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "ISIkJSMmJyonKCk=", // "!\"#$%&'()*"
    "", // Empty string is technically a valid base64
  ];

  for (const str of validBase64Strings) {
    expect(str + z.string().base64().safeParse(str).success).toBe(`${str}true`);
  }

  const invalidBase64Strings = [
    "12345", // Not padded correctly, not a multiple of 4 characters
    "SGVsbG8gV29ybGQ", // Missing padding
    "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw", // Missing padding
    "!UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // Invalid character '!'
    "?QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // Invalid character '?'
    ".MTIzND2Nzg5MC4=", // Invalid character '.'
    "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo", // Missing padding
    // Whitespace is not part of canonical base64 (RFC 4648 ยง3.3) โ€” atob() strips whitespace internally before validating, so the length check alone would accept "123 " etc.
    "123 ", // bypasses length-mod-4 via trailing whitespace
    "SGVsbG8gV29ybGQ= ", // trailing space
    " SGVsbG8gV29ybGQ=", // leading space
    "SGVsbG8gV29ybGQ=\n", // trailing newline
    "SGVs bG8gV29ybGQ=", // internal space
    "SGVs\nbG8gV29ybGQ=", // internal newline
    "SGVs\tbG8gV29ybGQ=", // internal tab
  ];

  for (const str of invalidBase64Strings) {
    expect(str + z.string().base64().safeParse(str).success).toBe(`${str}false`);
  }
});

test("base64url validations", () => {
  const base64url = z.string().base64url();

  const validBase64URLStrings = [
    "SGVsbG8gV29ybGQ", // "Hello World"

    "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw", // "This is an encoded string"

    "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms", // "Many hands make light work"

    "UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // "Patience is the key to success"
    "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg", // "Base64 encoding is fun"

    "MTIzNDU2Nzg5MA", // "1234567890"

    "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo", // "abcdefghijklmnopqrstuvwxyz"

    "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    "ISIkJSMmJyonKCk", // "!\"#$%&'()*"

    "", // Empty string is technically valid base64url
    "w7_Dv8O-w74K", // รฟรฟรพรพ
    "123456",
  ];

  for (const str of validBase64URLStrings) {
    expect(str + base64url.safeParse(str).success).toBe(`${str}true`);
  }

  const invalidBase64URLStrings = [
    "w7/Dv8O+w74K", // Has + and / characters (is base64)
    "A", // Invalid length (1 mod 4 carries no whole byte)
    "12345", // Invalid length (not a multiple of 4 characters when adding allowed number of padding characters)
    "12345===", // Not padded correctly
    "!UGF0aWVuY2UgaXMgdGhlIGtleSB0byBzdWNjZXNz", // Invalid character '!'
    "?QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // Invalid character '?'
    ".MTIzND2Nzg5MC4=", // Invalid character '.'

    // disallow valid padding
    "SGVsbG8gV29ybGQ=", // "Hello World" with padding
    "VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==", // "This is an encoded string" with padding
    "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcms=", // "Many hands make light work" with padding
    "QmFzZTY0IGVuY29kaW5nIGlzIGZ1bg==", // "Base64 encoding is fun" with padding
    "MTIzNDU2Nzg5MA==", // "1234567890" with padding
    "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo=", // "abcdefghijklmnopqrstuvwxyz with padding"
    "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVo=", // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" with padding
    "ISIkJSMmJyonKCk=", // "!\"#$%&'()*" with padding
  ];

  for (const str of invalidBase64URLStrings) {
    expect(str + base64url.safeParse(str).success).toBe(`${str}false`);
  }
});

test("big base64 and base64url", () => {
  const bigbase64 = randomBytes(1024 * 1024 * 10).toString("base64");
  z.base64().parse(bigbase64);
  const bigbase64url = randomBytes(1024 * 1024 * 10).toString("base64url");
  z.base64url().parse(bigbase64url);

  // template literals compose def.pattern and test it on every parse; the quantified block forms overflowed the regex stack here
  expect(z.templateLiteral(["id-", z.base64()]).safeParse(`id-${bigbase64}`).success).toBe(true);
  expect(z.templateLiteral(["id-", z.base64url()]).safeParse(`id-${bigbase64url}`).success).toBe(true);
});

test("template literal composes base64 without alternation leaks", () => {
  // the ^$| alternation in regexes.base64 used to leak: "AAAA" matched with the prefix dropped and "id-AAAA" was rejected
  const tl = z.templateLiteral(["id-", z.base64()]);
  expect(tl.safeParse("id-AAAA").success).toBe(true);
  expect(tl.safeParse("id-").success).toBe(true);
  expect(tl.safeParse("AAAA").success).toBe(false);
});

function makeJwt(header: object, payload: object) {
  const headerBase64 = Buffer.from(JSON.stringify(header)).toString("base64url");
  const payloadBase64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
  const signature = "signature"; // Placeholder for the signature
  return `${headerBase64}.${payloadBase64}.${signature}`;
}

test("jwt token", () => {
  const jwt = z.string().jwt();
  expect(() => jwt.parse("invalid")).toThrow();
  expect(() => jwt.parse("invalid.invalid")).toThrow();
  expect(() => jwt.parse("invalid.invalid.invalid")).toThrow();

  // Valid JWTs
  const es256jwt = z.string().jwt({ alg: "ES256" });
  const d1 = makeJwt({ typ: "JWT", alg: "ES256" }, {});
  jwt.parse(d1);
  es256jwt.parse(d1);

  // Invalid header
  const d2 = makeJwt({}, {});
  expect(() => jwt.parse(d2)).toThrow();

  // Wrong algorithm
  const d3 = makeJwt({ typ: "JWT", alg: "RS256" }, {});
  expect(() => es256jwt.parse(d3)).toThrow();

  // missing typ is fine
  const d4 = makeJwt({ alg: "HS256" }, {});
  jwt.parse(d4);

  // type isn't JWT
  const d5 = makeJwt({ typ: "SUP", alg: "HS256" }, { foo: "bar" });
  expect(() => jwt.parse(d5)).toThrow();
});

test("url validations", () => {
  const url = z.string().url();
  url.parse("http://google.com");
  url.parse("https://google.com/asdf?asdf=ljk3lk4&asdf=234#asdf");
  url.parse("https://anonymous:flabada@developer.mozilla.org/en-US/docs/Web/API/URL/password");
  url.parse("https://localhost");
  url.parse("https://my.local");
  url.parse("http://aslkfjdalsdfkjaf");
  url.parse("http://localhost");

  url.parse("c:");

  expect(() => url.parse("asdf")).toThrow();
  expect(() => url.parse("https:/")).toThrow();
  expect(() => url.parse("asdfj@lkjsdf.com")).toThrow();
  expect(() => url.parse("https://")).toThrow();
});

test("url preserves original input", () => {
  const url = z.string().url();

  // Test the specific case from the user report
  const input = "https://example.com?key=NUXOmHqWNVTapJkJJHw8BfD155AuqhH_qju_5fNmQ4ZHV7u8";
  const output = url.parse(input);
  expect(output).toBe(input); // Should preserve the original input exactly

  // Test other cases where URL constructor would normalize
  expect(url.parse("https://example.com?foo=bar")).toBe("https://example.com?foo=bar");
  expect(url.parse("http://example.com?test=123")).toBe("http://example.com?test=123");
  expect(url.parse("https://sub.example.com?param=value&other=data")).toBe(
    "https://sub.example.com?param=value&other=data"
  );

  // Test cases with trailing slashes are preserved
  expect(url.parse("https://example.com/")).toBe("https://example.com/");
  expect(url.parse("https://example.com/path/")).toBe("https://example.com/path/");

  // Test cases with paths and query parameters
  expect(url.parse("https://example.com/path?query=param")).toBe("https://example.com/path?query=param");
});

test("url trims whitespace", () => {
  const url = z.string().url();

  // Test trimming whitespace from URLs
  expect(url.parse("  https://example.com  ")).toBe("https://example.com");
  expect(url.parse("  https://example.com/path?query=param  ")).toBe("https://example.com/path?query=param");
  expect(url.parse("\t\nhttps://example.com\t\n")).toBe("https://example.com");
  expect(url.parse("   https://example.com?key=value   ")).toBe("https://example.com?key=value");

  // Test that URLs without extra whitespace are unchanged
  expect(url.parse("https://example.com")).toBe("https://example.com");
  expect(url.parse("https://example.com/path")).toBe("https://example.com/path");
});

test("url returns the string the parser validated", () => {
  // The URL parser deletes ASCII tab, LF and CR instead of failing, so `new URL()` reports on a string that is not the one it was given. The host is the consequential case: this validated example.com and used to hand back a URL naming a different host.
  expect(z.url().parse("https://exa\nmple.com")).toBe("https://example.com");
  expect(z.url().parse("https://exa\tmple.com")).toBe("https://example.com");
  expect(z.url().parse("https://exa\rmple.com")).toBe("https://example.com");
  expect(z.httpUrl().parse("https://exa\nmple.com")).toBe("https://example.com");
  expect(z.url({ hostname: /^a\.com$/ }).parse("https://a\n.com")).toBe("https://a.com");
  expect(z.url().parse("https://example.com/a\nb?c=\td#e")).toBe("https://example.com/ab?c=d#e");

  // Nothing that parsed before stops parsing, and normalize still wins where it applies.
  expect(z.url().parse("https://example.com/path")).toBe("https://example.com/path");
  expect(z.url({ normalize: true }).parse("https://exa\nmple.com")).toBe("https://example.com/");
});

test("ipv6 and cidrv6 reject anything outside the address alphabet", () => {
  // `new URL("http://[...]")` parses an authority rather than an address, so a delimiter re-splits it and the parser validates something else entirely.
  expect(z.ipv6().safeParse("::@1\\").success).toBe(false); // used to validate against the host 0.0.0.1
  expect(z.ipv6().safeParse("::]/1").success).toBe(false);
  expect(z.ipv6().safeParse("@[::1").success).toBe(false);
  expect(z.cidrv6().safeParse("::@1\\/64").success).toBe(false);

  for (const c of ["\t", "\n", "\r"]) {
    expect(z.ipv6().safeParse(`2001:db8::${c}1`).success).toBe(false);
    expect(z.ipv6().safeParse(`::1${c}`).success).toBe(false);
    expect(z.cidrv6().safeParse(`::1${c}/64`).success).toBe(false);
  }

  // A rejection has to surface as an issue, not just success: false.
  const result = z.ipv6().safeParse("::1\n");
  expect(result.success).toBe(false);
  expect(result.error!.issues[0]).toMatchObject({ code: "invalid_format", format: "ipv6" });

  expect(z.ipv6().parse("2001:db8::1")).toBe("2001:db8::1");
  expect(z.ipv6().parse("::ffff:192.0.2.1")).toBe("::ffff:192.0.2.1");
  expect(z.ipv6().parse("2001:DB8::1")).toBe("2001:DB8::1");
  expect(z.cidrv6().parse("::ffff:192.0.2.1/96")).toBe("::ffff:192.0.2.1/96");
});

test("url normalize flag", () => {
  const normalizeUrl = z.url({ normalize: true });
  const preserveUrl = z.url(); // normalize: false/undefined by default

  // Test that normalize flag causes URL normalization
  expect(normalizeUrl.parse("https://example.com?key=value")).toBe("https://example.com/?key=value");
  expect(normalizeUrl.parse("http://example.com?test=123")).toBe("http://example.com/?test=123");

  // Test with already normalized URLs
  expect(normalizeUrl.parse("https://example.com/")).toBe("https://example.com/");
  expect(normalizeUrl.parse("https://example.com/path?query=param")).toBe("https://example.com/path?query=param");

  // Test complex URLs with normalization
  expect(normalizeUrl.parse("https://example.com/../?key=value")).toBe("https://example.com/?key=value");
  expect(normalizeUrl.parse("https://example.com/./path?key=value")).toBe("https://example.com/path?key=value");

  // Compare with non-normalize behavior
  expect(preserveUrl.parse("https://example.com?key=value")).toBe("https://example.com?key=value");
  expect(preserveUrl.parse("http://example.com?test=123")).toBe("http://example.com?test=123");

  // Test trimming with normalize
  expect(normalizeUrl.parse("  https://example.com?key=value  ")).toBe("https://example.com/?key=value");
  expect(preserveUrl.parse("  https://example.com?key=value  ")).toBe("https://example.com?key=value");
});

test("url normalize with hostname and protocol constraints", () => {
  const constrainedNormalizeUrl = z.url({
    normalize: true,
    protocol: /^https$/,
    hostname: /^example\.com$/,
  });

  // Test that normalization works with constraints
  expect(constrainedNormalizeUrl.parse("https://example.com?key=value")).toBe("https://example.com/?key=value");

  // Test that constraints are still enforced
  expect(() => constrainedNormalizeUrl.parse("http://example.com?key=value")).toThrow();
  expect(() => constrainedNormalizeUrl.parse("https://other.com?key=value")).toThrow();
});

test("httpurl", () => {
  const httpUrl = z.url({
    protocol: /^https?$/,
    hostname: z.regexes.domain,
    // /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/
  });

  httpUrl.parse("https://example.com");
  httpUrl.parse("http://example.com");
  // ports
  httpUrl.parse("https://example.com:8080");
  httpUrl.parse("http://example.com:8080");
  // subdomains
  httpUrl.parse("https://sub.example.com");
  httpUrl.parse("http://sub.example.com");
  // paths
  httpUrl.parse("https://example.com/path/to/resource");
  httpUrl.parse("http://example.com/path/to/resource");
  // query parameters
  httpUrl.parse("https://example.com/path?query=param");
  httpUrl.parse("http://example.com/path?query=param");
  // fragment identifiers
  httpUrl.parse("https://example.com/path#fragment");
  httpUrl.parse("http://example.com/path#fragment");
  // fails
  expect(() => httpUrl.parse("ftp://example.com")).toThrow();
  expect(() => httpUrl.parse("shttp://example.com")).toThrow();
  expect(() => httpUrl.parse("httpz://example.com")).toThrow();
  expect(() => httpUrl.parse("http://")).toThrow();
  expect(() => httpUrl.parse("http://localhost")).toThrow();
  expect(() => httpUrl.parse("http://-asdf.com")).toThrow();
  expect(() =>
    httpUrl.parse(
      "http://asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf.com"
    )
  ).toThrow();
  expect(() => httpUrl.parse("http://asdf.c")).toThrow();
  expect(() => httpUrl.parse("mailto:asdf@lckj.com")).toThrow();
  // total host length over the RFC 1035 limit of 253 chars (built from valid-length labels)
  const longHost = `${`${"a".repeat(50)}.`.repeat(5)}com`; // 5 * 51 + 3 = 258 chars
  expect(longHost.length).toBeGreaterThan(253);
  expect(() => httpUrl.parse(`http://${longHost}`)).toThrow();
  // TLD over the 63-char label limit
  expect(() => httpUrl.parse(`http://example.${"a".repeat(64)}`)).toThrow();
  // a host at exactly the 253-char limit is still accepted, one char more is not
  const maxHost = `${`${"a".repeat(61)}.`.repeat(4)}aaaaa`; // 4 * 62 + 5 = 253 chars
  httpUrl.parse(`http://${maxHost}`);
  expect(() => httpUrl.parse(`http://${maxHost}a`)).toThrow();
  // missing // after protocol
  expect(() => httpUrl.parse("http:example.com")).toThrow();
  expect(() => httpUrl.parse("https:example.com")).toThrow();
  // missing one /
  expect(() => httpUrl.parse("https:/www.google.com")).toThrow();
  expect(() => httpUrl.parse("http:/example.com")).toThrow();
});

test("url error overrides", () => {
  try {
    z.string().url().parse("https");
  } catch (err) {
    expect((err as z.ZodError).issues[0].message).toEqual("Invalid URL");
  }
  try {
    z.string().url("badurl").parse("https");
  } catch (err) {
    expect((err as z.ZodError).issues[0].message).toEqual("badurl");
  }
  try {
    z.string().url({ message: "badurl" }).parse("https");
  } catch (err) {
    expect((err as z.ZodError).issues[0].message).toEqual("badurl");
  }
});

test("emoji validations", () => {
  const emoji = z.string().emoji();

  emoji.parse("๐Ÿฆฐ๐Ÿฆฑ๐Ÿฆฒ๐Ÿฆณ"); // both Extended_Pictographic and Emoji_Component
  emoji.parse("๐Ÿ‘‹๐Ÿ‘‹๐Ÿ‘‹๐Ÿ‘‹");
  emoji.parse("๐Ÿบ๐Ÿ‘ฉโ€๐Ÿš€๐Ÿซก");
  emoji.parse("๐Ÿ’š๐Ÿ’™๐Ÿ’œ๐Ÿ’›โค๏ธ");
  emoji.parse("๐Ÿ›๐Ÿ—๐Ÿ๐Ÿก๐ŸŽฆ๐Ÿšข๐Ÿจ๐Ÿ’ซ๐ŸŽŒโ˜˜๐Ÿ—ก๐Ÿ˜น๐Ÿ”’๐ŸŽฌโžก๏ธ๐Ÿน๐Ÿ—‚๐Ÿšจโšœ๐Ÿ•‘ใ€ฝ๏ธ๐Ÿšฆ๐ŸŒŠ๐Ÿด๐Ÿ’๐ŸŒ๐Ÿ’ฐ๐Ÿ˜ณ๐ŸŒบ๐Ÿƒ");
  emoji.parse("๐Ÿ‡น๐Ÿ‡ท๐Ÿคฝ๐Ÿฟโ€โ™‚๏ธ");
  emoji.parse(
    "๐Ÿ˜€๐Ÿ˜๐Ÿ˜‚๐Ÿคฃ๐Ÿ˜ƒ๐Ÿ˜„๐Ÿ˜…๐Ÿ˜†๐Ÿ˜‰๐Ÿ˜Š๐Ÿ˜‹๐Ÿ˜Ž๐Ÿ˜๐Ÿ˜˜๐Ÿฅฐ๐Ÿ˜—๐Ÿ˜™๐Ÿ˜šโ˜บ๏ธโ˜บ๐Ÿ™‚๐Ÿค—๐Ÿคฉ๐Ÿค”๐Ÿคจ๐Ÿ˜๐Ÿ˜‘๐Ÿ˜ถ๐Ÿ™„๐Ÿ˜๐Ÿ˜ฃ๐Ÿ˜ฅ๐Ÿ˜ฎ๐Ÿค๐Ÿ˜ฏ๐Ÿ˜ช๐Ÿ˜ซ๐Ÿ˜ด๐Ÿ˜Œ๐Ÿ˜›๐Ÿ˜œ๐Ÿ˜๐Ÿคค๐Ÿ˜’๐Ÿ˜“๐Ÿ˜”๐Ÿ˜•๐Ÿ™ƒ๐Ÿค‘๐Ÿ˜ฒโ˜น๏ธโ˜น๐Ÿ™๐Ÿ˜–๐Ÿ˜ž๐Ÿ˜Ÿ๐Ÿ˜ค๐Ÿ˜ข๐Ÿ˜ญ๐Ÿ˜ฆ๐Ÿ˜ง๐Ÿ˜จ๐Ÿ˜ฉ๐Ÿคฏ๐Ÿ˜ฌ๐Ÿ˜ฐ๐Ÿ˜ฑ๐Ÿฅต๐Ÿฅถ๐Ÿ˜ณ๐Ÿคช๐Ÿ˜ต๐Ÿ˜ก๐Ÿ˜ ๐Ÿคฌ๐Ÿ˜ท๐Ÿค’๐Ÿค•๐Ÿคข๐Ÿคฎ๐Ÿคง๐Ÿ˜‡๐Ÿค ๐Ÿฅณ๐Ÿฅด๐Ÿฅบ๐Ÿคฅ๐Ÿคซ๐Ÿคญ๐Ÿง๐Ÿค“๐Ÿ˜ˆ๐Ÿ‘ฟ๐Ÿคก๐Ÿ‘น๐Ÿ‘บ๐Ÿ’€โ˜ ๏ธโ˜ ๐Ÿ‘ป๐Ÿ‘ฝ๐Ÿ‘พ๐Ÿค–๐Ÿ’ฉ๐Ÿ˜บ๐Ÿ˜ธ๐Ÿ˜น๐Ÿ˜ป๐Ÿ˜ผ๐Ÿ˜ฝ๐Ÿ™€๐Ÿ˜ฟ๐Ÿ˜พ๐Ÿ™ˆ๐Ÿ™‰๐Ÿ™Š๐Ÿป๐Ÿผ๐Ÿฝ๐Ÿพ๐Ÿฟ๐Ÿ‘ถ๐Ÿ‘ถ๐Ÿป๐Ÿ‘ถ๐Ÿผ๐Ÿ‘ถ๐Ÿฝ๐Ÿ‘ถ๐Ÿพ๐Ÿ‘ถ๐Ÿฟ๐Ÿง’๐Ÿง’๐Ÿป๐Ÿง’๐Ÿผ๐Ÿง’๐Ÿฝ๐Ÿง’๐Ÿพ๐Ÿง’๐Ÿฟ๐Ÿ‘ฆ๐Ÿ‘ฆ๐Ÿป๐Ÿ‘ฆ๐Ÿผ๐Ÿ‘ฆ๐Ÿฝ๐Ÿ‘ฆ๐Ÿพ๐Ÿ‘ฆ๐Ÿฟ๐Ÿ‘ง๐Ÿ‘ง๐Ÿป๐Ÿ‘ง๐Ÿผ๐Ÿ‘ง๐Ÿฝ๐Ÿ‘ง๐Ÿพ๐Ÿ‘ง๐Ÿฟ๐Ÿง‘๐Ÿง‘๐Ÿป๐Ÿง‘๐Ÿผ๐Ÿง‘๐Ÿฝ๐Ÿง‘๐Ÿพ๐Ÿง‘๐Ÿฟ๐Ÿ‘จ๐Ÿ‘จ๐Ÿป๐Ÿ‘จ๐Ÿผ๐Ÿ‘จ๐Ÿฝ๐Ÿ‘จ๐Ÿพ๐Ÿ‘จ๐Ÿฟ๐Ÿ‘ฉ๐Ÿ‘ฉ๐Ÿป๐Ÿ‘ฉ๐Ÿผ๐Ÿ‘ฉ๐Ÿฝ๐Ÿ‘ฉ๐Ÿพ๐Ÿ‘ฉ๐Ÿฟ๐Ÿง“๐Ÿง“๐Ÿป๐Ÿง“๐Ÿผ๐Ÿง“๐Ÿฝ๐Ÿง“๐Ÿพ๐Ÿง“๐Ÿฟ๐Ÿ‘ด๐Ÿ‘ด๐Ÿป๐Ÿ‘ด๐Ÿผ๐Ÿ‘ด๐Ÿฝ๐Ÿ‘ด๐Ÿพ๐Ÿ‘ด๐Ÿฟ๐Ÿ‘ต๐Ÿ‘ต๐Ÿป๐Ÿ‘ต๐Ÿผ๐Ÿ‘ต๐Ÿฝ๐Ÿ‘ต๐Ÿพ๐Ÿ‘ต๐Ÿฟ๐Ÿ‘จโ€โš•๏ธ๐Ÿ‘จโ€โš•๐Ÿ‘จ๐Ÿปโ€โš•๏ธ๐Ÿ‘จ๐Ÿปโ€โš•๐Ÿ‘จ๐Ÿผโ€โš•๏ธ๐Ÿ‘จ๐Ÿผโ€โš•๐Ÿ‘จ๐Ÿฝโ€โš•๏ธ๐Ÿ‘จ๐Ÿฝโ€โš•๐Ÿ‘จ๐Ÿพโ€โš•๏ธ๐Ÿ‘จ๐Ÿพโ€โš•๐Ÿ‘จ๐Ÿฟโ€โš•๏ธ๐Ÿ‘จ๐Ÿฟโ€โš•๐Ÿ‘ฉโ€โš•๏ธ๐Ÿ‘ฉโ€โš•๐Ÿ‘ฉ๐Ÿปโ€โš•๏ธ๐Ÿ‘ฉ๐Ÿปโ€โš•๐Ÿ‘ฉ๐Ÿผโ€โš•๏ธ๐Ÿ‘ฉ๐Ÿผโ€โš•๐Ÿ‘ฉ๐Ÿฝโ€โš•๏ธ๐Ÿ‘ฉ๐Ÿฝโ€โš•๐Ÿ‘ฉ๐Ÿพโ€โš•๏ธ๐Ÿ‘ฉ๐Ÿพโ€โš•๐Ÿ‘ฉ๐Ÿฟโ€โš•๏ธ๐Ÿ‘ฉ๐Ÿฟโ€โš•๐Ÿ‘จโ€๐ŸŽ“๐Ÿ‘จ๐Ÿปโ€๐ŸŽ“๐Ÿ‘จ๐Ÿผโ€๐ŸŽ“๐Ÿ‘จ๐Ÿฝโ€๐ŸŽ“๐Ÿ‘จ๐Ÿพโ€๐ŸŽ“๐Ÿ‘จ๐Ÿฟโ€๐ŸŽ“๐Ÿ‘ฉโ€๐ŸŽ“๐Ÿ‘ฉ๐Ÿปโ€๐ŸŽ“๐Ÿ‘ฉ๐Ÿผโ€๐ŸŽ“๐Ÿ‘ฉ๐Ÿฝโ€๐ŸŽ“๐Ÿ‘ฉ๐Ÿพโ€๐ŸŽ“๐Ÿ‘ฉ๐Ÿฟโ€๐ŸŽ“๐Ÿ‘จโ€๐Ÿซ๐Ÿ‘จ๐Ÿปโ€๐Ÿซ๐Ÿ‘จ๐Ÿผโ€๐Ÿซ๐Ÿ‘จ๐Ÿฝโ€๐Ÿซ๐Ÿ‘จ๐Ÿพโ€๐Ÿซ๐Ÿ‘จ๐Ÿฟโ€๐Ÿซ๐Ÿ‘ฉโ€๐Ÿซ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿซ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿซ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿซ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿซ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿซ๐Ÿ‘จโ€โš–๏ธ๐Ÿ‘จโ€โš–๐Ÿ‘จ๐Ÿปโ€โš–๏ธ๐Ÿ‘จ๐Ÿปโ€โš–๐Ÿ‘จ๐Ÿผโ€โš–๏ธ๐Ÿ‘จ๐Ÿผโ€โš–๐Ÿ‘จ๐Ÿฝโ€โš–๏ธ๐Ÿ‘จ๐Ÿฝโ€โš–๐Ÿ‘จ๐Ÿพโ€โš–๏ธ๐Ÿ‘จ๐Ÿพโ€โš–๐Ÿ‘จ๐Ÿฟโ€โš–๏ธ๐Ÿ‘จ๐Ÿฟโ€โš–๐Ÿ‘ฉโ€โš–๏ธ๐Ÿ‘ฉโ€โš–๐Ÿ‘ฉ๐Ÿปโ€โš–๏ธ๐Ÿ‘ฉ๐Ÿปโ€โš–๐Ÿ‘ฉ๐Ÿผโ€โš–๏ธ๐Ÿ‘ฉ๐Ÿผโ€โš–๐Ÿ‘ฉ๐Ÿฝโ€โš–๏ธ๐Ÿ‘ฉ๐Ÿฝโ€โš–๐Ÿ‘ฉ๐Ÿพโ€โš–๏ธ๐Ÿ‘ฉ๐Ÿพโ€โš–๐Ÿ‘ฉ๐Ÿฟโ€โš–๏ธ๐Ÿ‘ฉ๐Ÿฟโ€โš–๐Ÿ‘จโ€๐ŸŒพ๐Ÿ‘จ๐Ÿปโ€๐ŸŒพ๐Ÿ‘จ๐Ÿผโ€๐ŸŒพ๐Ÿ‘จ๐Ÿฝโ€๐ŸŒพ๐Ÿ‘จ๐Ÿพโ€๐ŸŒพ๐Ÿ‘จ๐Ÿฟโ€๐ŸŒพ๐Ÿ‘ฉโ€๐ŸŒพ๐Ÿ‘ฉ๐Ÿปโ€๐ŸŒพ๐Ÿ‘ฉ๐Ÿผโ€๐ŸŒพ๐Ÿ‘ฉ๐Ÿฝโ€๐ŸŒพ๐Ÿ‘ฉ๐Ÿพโ€๐ŸŒพ๐Ÿ‘ฉ๐Ÿฟโ€๐ŸŒพ๐Ÿ‘จโ€๐Ÿณ๐Ÿ‘จ๐Ÿปโ€๐Ÿณ๐Ÿ‘จ๐Ÿผโ€๐Ÿณ๐Ÿ‘จ๐Ÿฝโ€๐Ÿณ๐Ÿ‘จ๐Ÿพโ€๐Ÿณ๐Ÿ‘จ๐Ÿฟโ€๐Ÿณ๐Ÿ‘ฉโ€๐Ÿณ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿณ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿณ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿณ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿณ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿณ๐Ÿ‘จโ€๐Ÿ”ง๐Ÿ‘จ๐Ÿปโ€๐Ÿ”ง๐Ÿ‘จ๐Ÿผโ€๐Ÿ”ง๐Ÿ‘จ๐Ÿฝโ€๐Ÿ”ง๐Ÿ‘จ๐Ÿพโ€๐Ÿ”ง๐Ÿ‘จ๐Ÿฟโ€๐Ÿ”ง๐Ÿ‘ฉโ€๐Ÿ”ง๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ”ง๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ”ง๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ”ง๐Ÿ‘ฉ๐Ÿพโ€๐Ÿ”ง๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ”ง๐Ÿ‘จโ€๐Ÿญ๐Ÿ‘จ๐Ÿปโ€๐Ÿญ๐Ÿ‘จ๐Ÿผโ€๐Ÿญ๐Ÿ‘จ๐Ÿฝโ€๐Ÿญ๐Ÿ‘จ๐Ÿพโ€๐Ÿญ๐Ÿ‘จ๐Ÿฟโ€๐Ÿญ๐Ÿ‘ฉโ€๐Ÿญ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿญ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿญ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿญ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿญ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿญ๐Ÿ‘จโ€๐Ÿ’ผ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ผ๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ผ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ผ๐Ÿ‘จ๐Ÿพโ€๐Ÿ’ผ๐Ÿ‘จ๐Ÿฟโ€๐Ÿ’ผ๐Ÿ‘ฉโ€๐Ÿ’ผ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ผ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ผ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ’ผ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿ’ผ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ’ผ๐Ÿ‘จโ€๐Ÿ”ฌ๐Ÿ‘จ๐Ÿปโ€๐Ÿ”ฌ๐Ÿ‘จ๐Ÿผโ€๐Ÿ”ฌ๐Ÿ‘จ๐Ÿฝโ€๐Ÿ”ฌ๐Ÿ‘จ๐Ÿพโ€๐Ÿ”ฌ๐Ÿ‘จ๐Ÿฟโ€๐Ÿ”ฌ๐Ÿ‘ฉโ€๐Ÿ”ฌ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ”ฌ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ”ฌ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ”ฌ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿ”ฌ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ”ฌ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿผโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿฝโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿพโ€๐Ÿ’ป๐Ÿ‘จ๐Ÿฟโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿผโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿพโ€๐Ÿ’ป๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿ’ป๐Ÿ‘จโ€๐ŸŽค๐Ÿ‘จ๐Ÿปโ€๐ŸŽค๐Ÿ‘จ๐Ÿผโ€๐ŸŽค๐Ÿ‘จ๐Ÿฝโ€๐ŸŽค๐Ÿ‘จ๐Ÿพโ€๐ŸŽค๐Ÿ‘จ๐Ÿฟโ€๐ŸŽค๐Ÿ‘ฉโ€๐ŸŽค๐Ÿ‘ฉ๐Ÿปโ€๐ŸŽค๐Ÿ‘ฉ๐Ÿผโ€๐ŸŽค๐Ÿ‘ฉ๐Ÿฝโ€๐ŸŽค๐Ÿ‘ฉ๐Ÿพโ€๐ŸŽค๐Ÿ‘ฉ๐Ÿฟโ€๐ŸŽค๐Ÿ‘จโ€๐ŸŽจ๐Ÿ‘จ๐Ÿปโ€๐ŸŽจ๐Ÿ‘จ๐Ÿผโ€๐ŸŽจ๐Ÿ‘จ๐Ÿฝโ€๐ŸŽจ๐Ÿ‘จ๐Ÿพโ€๐ŸŽจ๐Ÿ‘จ๐Ÿฟโ€๐ŸŽจ๐Ÿ‘ฉโ€๐ŸŽจ๐Ÿ‘ฉ๐Ÿปโ€๐ŸŽจ๐Ÿ‘ฉ๐Ÿผโ€๐ŸŽจ๐Ÿ‘ฉ๐Ÿฝโ€๐ŸŽจ๐Ÿ‘ฉ๐Ÿพโ€๐ŸŽจ๐Ÿ‘ฉ๐Ÿฟโ€๐ŸŽจ๐Ÿ‘จโ€โœˆ๏ธ๐Ÿ‘จโ€โœˆ๐Ÿ‘จ๐Ÿปโ€โœˆ๏ธ๐Ÿ‘จ๐Ÿปโ€โœˆ๐Ÿ‘จ๐Ÿผโ€โœˆ๏ธ๐Ÿ‘จ๐Ÿผโ€โœˆ๐Ÿ‘จ๐Ÿฝโ€โœˆ๏ธ๐Ÿ‘จ๐Ÿฝโ€โœˆ๐Ÿ‘จ๐Ÿพโ€โœˆ๏ธ๐Ÿ‘จ๐Ÿพโ€โœˆ๐Ÿ‘จ๐Ÿฟโ€โœˆ๏ธ๐Ÿ‘จ๐Ÿฟโ€โœˆ๐Ÿ‘ฉโ€โœˆ๏ธ๐Ÿ‘ฉโ€โœˆ๐Ÿ‘ฉ๐Ÿปโ€โœˆ๏ธ๐Ÿ‘ฉ๐Ÿปโ€โœˆ๐Ÿ‘ฉ๐Ÿผโ€โœˆ๏ธ๐Ÿ‘ฉ๐Ÿผโ€โœˆ๐Ÿ‘ฉ๐Ÿฝโ€โœˆ๏ธ๐Ÿ‘ฉ๐Ÿฝโ€โœˆ๐Ÿ‘ฉ๐Ÿพโ€โœˆ๏ธ๐Ÿ‘ฉ๐Ÿพโ€โœˆ๐Ÿ‘ฉ๐Ÿฟโ€โœˆ๏ธ๐Ÿ‘ฉ๐Ÿฟโ€โœˆ๐Ÿ‘จโ€๐Ÿš€๐Ÿ‘จ๐Ÿปโ€๐Ÿš€๐Ÿ‘จ๐Ÿผโ€๐Ÿš€๐Ÿ‘จ๐Ÿฝโ€๐Ÿš€๐Ÿ‘จ๐Ÿพโ€๐Ÿš€๐Ÿ‘จ๐Ÿฟโ€๐Ÿš€๐Ÿ‘ฉโ€๐Ÿš€๐Ÿ‘ฉ๐Ÿปโ€๐Ÿš€๐Ÿ‘ฉ๐Ÿผโ€๐Ÿš€๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿš€๐Ÿ‘ฉ๐Ÿพโ€๐Ÿš€๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿš€๐Ÿ‘จโ€๐Ÿš’๐Ÿ‘จ๐Ÿปโ€๐Ÿš’๐Ÿ‘จ๐Ÿผโ€๐Ÿš’๐Ÿ‘จ๐Ÿฝโ€๐Ÿš’๐Ÿ‘จ๐Ÿพโ€๐Ÿš’๐Ÿ‘จ๐Ÿฟโ€๐Ÿš’๐Ÿ‘ฉโ€๐Ÿš’๐Ÿ‘ฉ๐Ÿปโ€๐Ÿš’๐Ÿ‘ฉ๐Ÿผโ€๐Ÿš’๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿš’๐Ÿ‘ฉ๐Ÿพโ€๐Ÿš’๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿš’๐Ÿ‘ฎ๐Ÿ‘ฎ๐Ÿป๐Ÿ‘ฎ๐Ÿผ๐Ÿ‘ฎ๐Ÿฝ๐Ÿ‘ฎ๐Ÿพ๐Ÿ‘ฎ๐Ÿฟ๐Ÿ‘ฎโ€โ™‚๏ธ๐Ÿ‘ฎโ€โ™‚๐Ÿ‘ฎ๐Ÿปโ€โ™‚๏ธ๐Ÿ‘ฎ๐Ÿปโ€โ™‚๐Ÿ‘ฎ๐Ÿผโ€โ™‚๏ธ๐Ÿ‘ฎ๐Ÿผโ€โ™‚๐Ÿ‘ฎ๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ฎ๐Ÿฝโ€โ™‚๐Ÿ‘ฎ๐Ÿพโ€โ™‚๏ธ๐Ÿ‘ฎ๐Ÿพโ€โ™‚๐Ÿ‘ฎ๐Ÿฟโ€โ™‚๏ธ๐Ÿ‘ฎ๐Ÿฟโ€โ™‚๐Ÿ‘ฎโ€โ™€๏ธ๐Ÿ‘ฎโ€โ™€๐Ÿ‘ฎ๐Ÿปโ€โ™€๏ธ๐Ÿ‘ฎ๐Ÿปโ€โ™€๐Ÿ‘ฎ๐Ÿผโ€โ™€๏ธ๐Ÿ‘ฎ๐Ÿผโ€โ™€๐Ÿ‘ฎ๐Ÿฝโ€โ™€๏ธ๐Ÿ‘ฎ๐Ÿฝโ€โ™€๐Ÿ‘ฎ๐Ÿพโ€โ™€๏ธ๐Ÿ‘ฎ๐Ÿพโ€โ™€๐Ÿ‘ฎ๐Ÿฟโ€โ™€๏ธ๐Ÿ‘ฎ๐Ÿฟโ€โ™€๐Ÿ•ต๏ธ๐Ÿ•ต๐Ÿ•ต๐Ÿป๐Ÿ•ต๐Ÿผ๐Ÿ•ต๐Ÿฝ๐Ÿ•ต๐Ÿพ๐Ÿ•ต๐Ÿฟ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ•ตโ€โ™‚๏ธ๐Ÿ•ต๏ธโ€โ™‚๐Ÿ•ตโ€โ™‚๐Ÿ•ต๐Ÿปโ€โ™‚๏ธ๐Ÿ•ต๐Ÿปโ€โ™‚๐Ÿ•ต๐Ÿผโ€โ™‚๏ธ๐Ÿ•ต๐Ÿผโ€โ™‚๐Ÿ•ต๐Ÿฝโ€โ™‚๏ธ๐Ÿ•ต๐Ÿฝโ€โ™‚๐Ÿ•ต๐Ÿพโ€โ™‚๏ธ๐Ÿ•ต๐Ÿพโ€โ™‚๐Ÿ•ต๐Ÿฟโ€โ™‚๏ธ๐Ÿ•ต๐Ÿฟโ€โ™‚๐Ÿ•ต๏ธโ€โ™€๏ธ๐Ÿ•ตโ€โ™€๏ธ๐Ÿ•ต๏ธโ€โ™€๐Ÿ•ตโ€โ™€๐Ÿ•ต๐Ÿปโ€โ™€๏ธ๐Ÿ•ต๐Ÿปโ€โ™€๐Ÿ•ต๐Ÿผโ€โ™€๏ธ๐Ÿ•ต๐Ÿผโ€โ™€๐Ÿ•ต๐Ÿฝโ€โ™€๏ธ๐Ÿ•ต๐Ÿฝโ€โ™€๐Ÿ•ต๐Ÿพโ€โ™€๏ธ๐Ÿ•ต๐Ÿพโ€โ™€๐Ÿ•ต๐Ÿฟโ€โ™€๏ธ๐Ÿ•ต๐Ÿฟโ€โ™€๐Ÿ’‚๐Ÿ’‚๐Ÿป๐Ÿ’‚๐Ÿผ๐Ÿ’‚๐Ÿฝ๐Ÿ’‚๐Ÿพ๐Ÿ’‚๐Ÿฟ๐Ÿ’‚โ€โ™‚๏ธ๐Ÿ’‚โ€โ™‚๐Ÿ’‚๐Ÿปโ€โ™‚๏ธ๐Ÿ’‚๐Ÿปโ€โ™‚๐Ÿ’‚๐Ÿผโ€โ™‚๏ธ๐Ÿ’‚๐Ÿผโ€โ™‚๐Ÿ’‚๐Ÿฝโ€โ™‚๏ธ๐Ÿ’‚๐Ÿฝโ€โ™‚๐Ÿ’‚๐Ÿพโ€โ™‚๏ธ๐Ÿ’‚๐Ÿพโ€โ™‚๐Ÿ’‚๐Ÿฟโ€โ™‚๏ธ๐Ÿ’‚๐Ÿฟโ€โ™‚๐Ÿ’‚โ€โ™€๏ธ๐Ÿ’‚โ€โ™€๐Ÿ’‚๐Ÿปโ€โ™€๏ธ๐Ÿ’‚๐Ÿปโ€โ™€๐Ÿ’‚๐Ÿผโ€โ™€๏ธ๐Ÿ’‚๐Ÿผโ€โ™€๐Ÿ’‚๐Ÿฝโ€โ™€๏ธ๐Ÿ’‚๐Ÿฝโ€โ™€๐Ÿ’‚๐Ÿพโ€โ™€๏ธ๐Ÿ’‚๐Ÿพโ€โ™€๐Ÿ’‚๐Ÿฟโ€โ™€๏ธ๐Ÿ’‚๐Ÿฟโ€โ™€๐Ÿ‘ท๐Ÿ‘ท๐Ÿป๐Ÿ‘ท๐Ÿผ๐Ÿ‘ท๐Ÿฝ๐Ÿ‘ท๐Ÿพ๐Ÿ‘ท๐Ÿฟ๐Ÿ‘ทโ€โ™‚๏ธ๐Ÿ‘ทโ€โ™‚๐Ÿ‘ท๐Ÿปโ€โ™‚๏ธ๐Ÿ‘ท๐Ÿปโ€โ™‚๐Ÿ‘ท๐Ÿผโ€โ™‚๏ธ๐Ÿ‘ท๐Ÿผโ€โ™‚๐Ÿ‘ท๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ท๐Ÿฝโ€โ™‚๐Ÿ‘ท๐Ÿพโ€โ™‚๏ธ๐Ÿ‘ท๐Ÿพโ€โ™‚๐Ÿ‘ท๐Ÿฟโ€โ™‚๏ธ๐Ÿ‘ท๐Ÿฟโ€โ™‚๐Ÿ‘ทโ€โ™€๏ธ๐Ÿ‘ทโ€โ™€๐Ÿ‘ท๐Ÿปโ€โ™€๏ธ๐Ÿ‘ท๐Ÿปโ€โ™€๐Ÿ‘ท๐Ÿผโ€โ™€๏ธ๐Ÿ‘ท๐Ÿผโ€โ™€๐Ÿ‘ท๐Ÿฝโ€โ™€๏ธ๐Ÿ‘ท๐Ÿฝโ€โ™€๐Ÿ‘ท๐Ÿพโ€โ™€๏ธ๐Ÿ‘ท๐Ÿพโ€โ™€๐Ÿ‘ท๐Ÿฟโ€โ™€๏ธ๐Ÿ‘ท๐Ÿฟโ€โ™€๐Ÿคด๐Ÿคด๐Ÿป๐Ÿคด๐Ÿผ๐Ÿคด๐Ÿฝ๐Ÿคด๐Ÿพ๐Ÿคด๐Ÿฟ๐Ÿ‘ธ๐Ÿ‘ธ๐Ÿป๐Ÿ‘ธ๐Ÿผ๐Ÿ‘ธ๐Ÿฝ๐Ÿ‘ธ๐Ÿพ๐Ÿ‘ธ๐Ÿฟ๐Ÿ‘ณ๐Ÿ‘ณ๐Ÿป๐Ÿ‘ณ๐Ÿผ๐Ÿ‘ณ๐Ÿฝ๐Ÿ‘ณ๐Ÿพ๐Ÿ‘ณ๐Ÿฟ๐Ÿ‘ณโ€โ™‚๏ธ๐Ÿ‘ณโ€โ™‚๐Ÿ‘ณ๐Ÿปโ€โ™‚๏ธ๐Ÿ‘ณ๐Ÿปโ€โ™‚๐Ÿ‘ณ๐Ÿผโ€โ™‚๏ธ๐Ÿ‘ณ๐Ÿผโ€โ™‚๐Ÿ‘ณ๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ณ๐Ÿฝโ€โ™‚๐Ÿ‘ณ๐Ÿพโ€โ™‚๏ธ๐Ÿ‘ณ๐Ÿพโ€โ™‚๐Ÿ‘ณ๐Ÿฟโ€โ™‚๏ธ๐Ÿ‘ณ๐Ÿฟโ€โ™‚๐Ÿ‘ณโ€โ™€๏ธ๐Ÿ‘ณโ€โ™€๐Ÿ‘ณ๐Ÿปโ€โ™€๏ธ๐Ÿ‘ณ๐Ÿปโ€โ™€๐Ÿ‘ณ๐Ÿผโ€โ™€๏ธ๐Ÿ‘ณ๐Ÿผโ€โ™€๐Ÿ‘ณ๐Ÿฝโ€โ™€๏ธ๐Ÿ‘ณ๐Ÿฝโ€โ™€๐Ÿ‘ณ๐Ÿพโ€โ™€๏ธ๐Ÿ‘ณ๐Ÿพโ€โ™€๐Ÿ‘ณ๐Ÿฟโ€โ™€๏ธ๐Ÿ‘ณ๐Ÿฟโ€โ™€๐Ÿ‘ฒ๐Ÿ‘ฒ๐Ÿป๐Ÿ‘ฒ๐Ÿผ๐Ÿ‘ฒ๐Ÿฝ๐Ÿ‘ฒ๐Ÿพ๐Ÿ‘ฒ๐Ÿฟ๐Ÿง•๐Ÿง•๐Ÿป๐Ÿง•๐Ÿผ๐Ÿง•๐Ÿฝ๐Ÿง•๐Ÿพ๐Ÿง•๐Ÿฟ๐Ÿง”๐Ÿง”๐Ÿป๐Ÿง”๐Ÿผ๐Ÿง”๐Ÿฝ๐Ÿง”๐Ÿพ๐Ÿง”๐Ÿฟ๐Ÿ‘ฑ๐Ÿ‘ฑ๐Ÿป๐Ÿ‘ฑ๐Ÿผ๐Ÿ‘ฑ๐Ÿฝ๐Ÿ‘ฑ๐Ÿพ๐Ÿ‘ฑ๐Ÿฟ๐Ÿ‘ฑโ€โ™‚๏ธ๐Ÿ‘ฑโ€โ™‚๐Ÿ‘ฑ๐Ÿปโ€โ™‚๏ธ๐Ÿ‘ฑ๐Ÿปโ€โ™‚๐Ÿ‘ฑ๐Ÿผโ€โ™‚๏ธ๐Ÿ‘ฑ๐Ÿผโ€โ™‚๐Ÿ‘ฑ๐Ÿฝโ€โ™‚๏ธ๐Ÿ‘ฑ๐Ÿฝโ€โ™‚๐Ÿ‘ฑ๐Ÿพโ€โ™‚๏ธ๐Ÿ‘ฑ๐Ÿพโ€โ™‚๐Ÿ‘ฑ๐Ÿฟโ€โ™‚๏ธ๐Ÿ‘ฑ๐Ÿฟโ€โ™‚๐Ÿ‘ฑโ€โ™€๏ธ๐Ÿ‘ฑโ€โ™€๐Ÿ‘ฑ๐Ÿปโ€โ™€๏ธ๐Ÿ‘ฑ๐Ÿปโ€โ™€๐Ÿ‘ฑ๐Ÿผโ€โ™€๏ธ๐Ÿ‘ฑ๐Ÿผโ€โ™€๐Ÿ‘ฑ๐Ÿฝโ€โ™€๏ธ๐Ÿ‘ฑ๐Ÿฝโ€โ™€๐Ÿ‘ฑ๐Ÿพโ€โ™€๏ธ๐Ÿ‘ฑ๐Ÿพโ€โ™€๐Ÿ‘ฑ๐Ÿฟโ€โ™€๏ธ๐Ÿ‘ฑ๐Ÿฟโ€โ™€๐Ÿ‘จโ€๐Ÿฆฐ๐Ÿ‘จ๐Ÿปโ€๐Ÿฆฐ๐Ÿ‘จ๐Ÿผโ€๐Ÿฆฐ๐Ÿ‘จ๐Ÿฝโ€๐Ÿฆฐ๐Ÿ‘จ๐Ÿพโ€๐Ÿฆฐ๐Ÿ‘จ๐Ÿฟโ€๐Ÿฆฐ๐Ÿ‘ฉโ€๐Ÿฆฐ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿฆฐ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿฆฐ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿฆฐ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿฆฐ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿฆฐ๐Ÿ‘จโ€๐Ÿฆฑ๐Ÿ‘จ๐Ÿปโ€๐Ÿฆฑ๐Ÿ‘จ๐Ÿผโ€๐Ÿฆฑ๐Ÿ‘จ๐Ÿฝโ€๐Ÿฆฑ๐Ÿ‘จ๐Ÿพโ€๐Ÿฆฑ๐Ÿ‘จ๐Ÿฟโ€๐Ÿฆฑ๐Ÿ‘ฉโ€๐Ÿฆฑ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿฆฑ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿฆฑ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿฆฑ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿฆฑ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿฆฑ๐Ÿ‘จโ€๐Ÿฆฒ๐Ÿ‘จ๐Ÿปโ€๐Ÿฆฒ๐Ÿ‘จ๐Ÿผโ€๐Ÿฆฒ๐Ÿ‘จ๐Ÿฝโ€๐Ÿฆฒ๐Ÿ‘จ๐Ÿพโ€๐Ÿฆฒ๐Ÿ‘จ๐Ÿฟโ€๐Ÿฆฒ๐Ÿ‘ฉโ€๐Ÿฆฒ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿฆฒ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿฆฒ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿฆฒ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿฆฒ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿฆฒ๐Ÿ‘จโ€๐Ÿฆณ๐Ÿ‘จ๐Ÿปโ€๐Ÿฆณ๐Ÿ‘จ๐Ÿผโ€๐Ÿฆณ๐Ÿ‘จ๐Ÿฝโ€๐Ÿฆณ๐Ÿ‘จ๐Ÿพโ€๐Ÿฆณ๐Ÿ‘จ๐Ÿฟโ€๐Ÿฆณ๐Ÿ‘ฉโ€๐Ÿฆณ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿฆณ๐Ÿ‘ฉ๐Ÿผโ€๐Ÿฆณ๐Ÿ‘ฉ๐Ÿฝโ€๐Ÿฆณ๐Ÿ‘ฉ๐Ÿพโ€๐Ÿฆณ๐Ÿ‘ฉ๐Ÿฟโ€๐Ÿฆณ๐Ÿคต๐Ÿคต๐Ÿป๐Ÿคต๐Ÿผ๐Ÿคต๐Ÿฝ๐Ÿคต๐Ÿพ๐Ÿคต๐Ÿฟ๐Ÿ‘ฐ๐Ÿ‘ฐ๐Ÿป๐Ÿ‘ฐ๐Ÿผ๐Ÿ‘ฐ๐Ÿฝ๐Ÿ‘ฐ๐Ÿพ๐Ÿ‘ฐ๐Ÿฟ๐Ÿคฐ๐Ÿคฐ๐Ÿป๐Ÿคฐ๐Ÿผ๐Ÿคฐ๐Ÿฝ๐Ÿคฐ๐Ÿพ๐Ÿคฐ๐Ÿฟ๐Ÿคฑ๐Ÿคฑ๐Ÿป๐Ÿคฑ๐Ÿผ๐Ÿคฑ๐Ÿฝ๐Ÿคฑ๐Ÿพ๐Ÿคฑ๐Ÿฟ๐Ÿ‘ผ๐Ÿ‘ผ๐Ÿป๐Ÿ‘ผ๐Ÿผ๐Ÿ‘ผ๐Ÿฝ๐Ÿ‘ผ๐Ÿพ๐Ÿ‘ผ๐Ÿฟ๐ŸŽ…๐ŸŽ…๐Ÿป๐ŸŽ…๐Ÿผ๐ŸŽ…๐Ÿฝ๐ŸŽ…๐Ÿพ๐ŸŽ…๐Ÿฟ๐Ÿคถ๐Ÿคถ๐Ÿป๐Ÿคถ๐Ÿผ๐Ÿคถ๐Ÿฝ๐Ÿคถ๐Ÿพ๐Ÿคถ๐Ÿฟ๐Ÿฆธ๐Ÿฆธ๐Ÿป๐Ÿฆธ๐Ÿผ๐Ÿฆธ๐Ÿฝ๐Ÿฆธ๐Ÿพ๐Ÿฆธ๐Ÿฟ๐Ÿฆธโ€โ™€๏ธ๐Ÿฆธโ€โ™€๐Ÿฆธ๐Ÿปโ€โ™€๏ธ๐Ÿฆธ๐Ÿปโ€โ™€๐Ÿฆธ๐Ÿผโ€โ™€๏ธ๐Ÿฆธ๐Ÿผโ€โ™€๐Ÿฆธ๐Ÿฝโ€โ™€๏ธ๐Ÿฆธ๐Ÿฝโ€โ™€๐Ÿฆธ๐Ÿพโ€โ™€๏ธ๐Ÿฆธ๐Ÿพโ€โ™€๐Ÿฆธ๐Ÿฟโ€โ™€๏ธ๐Ÿฆธ๐Ÿฟโ€โ™€๐Ÿฆธโ€โ™‚๏ธ๐Ÿฆธโ€โ™‚๐Ÿฆธ๐Ÿปโ€โ™‚๏ธ๐Ÿฆธ๐Ÿปโ€โ™‚๐Ÿฆธ๐Ÿผโ€โ™‚๏ธ๐Ÿฆธ๐Ÿผโ€โ™‚๐Ÿฆธ๐Ÿฝโ€โ™‚๏ธ๐Ÿฆธ๐Ÿฝโ€โ™‚๐Ÿฆธ๐Ÿพโ€โ™‚๏ธ๐Ÿฆธ๐Ÿพโ€โ™‚๐Ÿฆธ๐Ÿฟโ€โ™‚๏ธ๐Ÿฆธ๐Ÿฟโ€โ™‚๐Ÿฆน๐Ÿฆน๐Ÿป๐Ÿฆน๐Ÿผ๐Ÿฆน๐Ÿฝ๐Ÿฆน๐Ÿพ๐Ÿฆน๐Ÿฟ๐Ÿฆนโ€โ™€๏ธ๐Ÿฆนโ€โ™€๐Ÿฆน๐Ÿปโ€โ™€๏ธ๐Ÿฆน๐Ÿปโ€โ™€๐Ÿฆน๐Ÿผโ€โ™€๏ธ๐Ÿฆน๐Ÿผโ€โ™€๐Ÿฆน๐Ÿฝโ€โ™€๏ธ๐Ÿฆน๐Ÿฝโ€โ™€๐Ÿฆน๐Ÿพโ€โ™€๏ธ๐Ÿฆน๐Ÿพโ€โ™€๐Ÿฆน๐Ÿฟโ€โ™€๏ธ๐Ÿฆน๐Ÿฟโ€โ™€๐Ÿฆนโ€โ™‚๏ธ๐Ÿฆนโ€โ™‚๐Ÿฆน๐Ÿปโ€โ™‚๏ธ๐Ÿฆน๐Ÿปโ€โ™‚๐Ÿฆน๐Ÿผโ€โ™‚๏ธ๐Ÿฆน๐Ÿผโ€โ™‚๐Ÿฆน๐Ÿฝโ€โ™‚๏ธ๐Ÿฆน๐Ÿฝโ€โ™‚๐Ÿฆน๐Ÿพโ€โ™‚๏ธ๐Ÿฆน๐Ÿพโ€โ™‚๐Ÿฆน๐Ÿฟโ€โ™‚๏ธ๐Ÿฆน๐Ÿฟโ€โ™‚๐Ÿง™๐Ÿง™๐Ÿป๐Ÿง™๐Ÿผ๐Ÿง™๐Ÿฝ๐Ÿง™๐Ÿพ๐Ÿง™๐Ÿฟ๐Ÿง™โ€โ™€๏ธ๐Ÿง™โ€โ™€๐Ÿง™๐Ÿปโ€โ™€๏ธ๐Ÿง™๐Ÿปโ€โ™€๐Ÿง™๐Ÿผโ€โ™€๏ธ๐Ÿง™๐Ÿผโ€โ™€๐Ÿง™๐Ÿฝโ€โ™€๏ธ๐Ÿง™๐Ÿฝโ€โ™€๐Ÿง™๐Ÿพโ€โ™€๏ธ๐Ÿง™๐Ÿพโ€โ™€๐Ÿง™๐Ÿฟโ€โ™€๏ธ๐Ÿง™๐Ÿฟโ€โ™€๐Ÿง™โ€โ™‚๏ธ๐Ÿง™โ€โ™‚๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿง™๐Ÿปโ€โ™‚๐Ÿง™๐Ÿผโ€โ™‚๏ธ๐Ÿง™๐Ÿผโ€โ™‚๐Ÿง™๐Ÿฝโ€โ™‚๏ธ๐Ÿง™๐Ÿฝโ€โ™‚๐Ÿง™๐Ÿพโ€โ™‚๏ธ๐Ÿง™๐Ÿพโ€โ™‚๐Ÿง™๐Ÿฟโ€โ™‚๏ธ๐Ÿง™๐Ÿฟโ€โ™‚๐Ÿงš๐Ÿงš๐Ÿป๐Ÿงš๐Ÿผ๐Ÿงš๐Ÿฝ๐Ÿงš๐Ÿพ๐Ÿงš๐Ÿฟ๐Ÿงšโ€โ™€๏ธ๐Ÿงšโ€โ™€๐Ÿงš๐Ÿปโ€โ™€๏ธ๐Ÿงš๐Ÿปโ€โ™€๐Ÿงš๐Ÿผโ€โ™€๏ธ๐Ÿงš๐Ÿผโ€โ™€๐Ÿงš๐Ÿฝโ€โ™€๏ธ๐Ÿงš๐Ÿฝโ€โ™€๐Ÿงš๐Ÿพโ€โ™€๏ธ๐Ÿงš๐Ÿพโ€โ™€๐Ÿงš๐Ÿฟโ€โ™€๏ธ๐Ÿงš๐Ÿฟโ€โ™€๐Ÿงšโ€โ™‚๏ธ๐Ÿงšโ€โ™‚๐Ÿงš๐Ÿปโ€โ™‚๏ธ๐Ÿงš๐Ÿปโ€โ™‚๐Ÿงš๐Ÿผโ€โ™‚๏ธ๐Ÿงš๐Ÿผโ€โ™‚๐Ÿงš๐Ÿฝโ€โ™‚๏ธ๐Ÿงš๐Ÿฝโ€โ™‚๐Ÿงš๐Ÿพโ€โ™‚๏ธ๐Ÿงš๐Ÿพโ€โ™‚๐Ÿงš๐Ÿฟโ€โ™‚๏ธ๐Ÿงš๐Ÿฟโ€โ™‚๐Ÿง›๐Ÿง›๐Ÿป๐Ÿง›๐Ÿผ๐Ÿง›๐Ÿฝ๐Ÿง›๐Ÿพ๐Ÿง›๐Ÿฟ๐Ÿง›โ€โ™€๏ธ๐Ÿง›โ€โ™€๐Ÿง›๐Ÿปโ€โ™€๏ธ๐Ÿง›๐Ÿปโ€โ™€๐Ÿง›๐Ÿผโ€โ™€๏ธ๐Ÿง›๐Ÿผโ€โ™€๐Ÿง›๐Ÿฝโ€โ™€๏ธ๐Ÿง›๐Ÿฝโ€โ™€๐Ÿง›๐Ÿพโ€โ™€๏ธ๐Ÿง›๐Ÿพโ€โ™€๐Ÿง›๐Ÿฟโ€โ™€๏ธ๐Ÿง›๐Ÿฟโ€โ™€๐Ÿง›โ€โ™‚๏ธ๐Ÿง›โ€โ™‚๐Ÿง›๐Ÿปโ€โ™‚๏ธ๐Ÿง›๐Ÿปโ€โ™‚๐Ÿง›๐Ÿผโ€โ™‚๏ธ๐Ÿง›๐Ÿผโ€โ™‚๐Ÿง›๐Ÿฝโ€โ™‚๏ธ๐Ÿง›๐Ÿฝโ€โ™‚๐Ÿง›๐Ÿพโ€โ™‚๏ธ๐Ÿง›๐Ÿพโ€โ™‚๐Ÿง›๐Ÿฟโ€โ™‚๏ธ๐Ÿง›๐Ÿฟโ€โ™‚๐Ÿงœ๐Ÿงœ๐Ÿป๐Ÿงœ๐Ÿผ๐Ÿงœ๐Ÿฝ๐Ÿงœ๐Ÿพ๐Ÿงœ๐Ÿฟ๐Ÿงœโ€โ™€๏ธ๐Ÿงœโ€โ™€๐Ÿงœ๐Ÿปโ€โ™€๏ธ๐Ÿงœ๐Ÿปโ€โ™€๐Ÿงœ๐Ÿผโ€โ™€๏ธ๐Ÿงœ๐Ÿผโ€โ™€๐Ÿงœ๐Ÿฝโ€โ™€๏ธ๐Ÿงœ๐Ÿฝโ€โ™€๐Ÿงœ๐Ÿพโ€โ™€๏ธ๐Ÿงœ๐Ÿพโ€โ™€๐Ÿงœ๐Ÿฟโ€โ™€๏ธ๐Ÿงœ๐Ÿฟโ€โ™€๐Ÿงœโ€โ™‚๏ธ๐Ÿงœโ€โ™‚๐Ÿงœ๐Ÿปโ€โ™‚๏ธ๐Ÿงœ๐Ÿปโ€โ™‚๐Ÿงœ๐Ÿผโ€โ™‚๏ธ๐Ÿงœ๐Ÿผโ€โ™‚๐Ÿงœ๐Ÿฝโ€โ™‚๏ธ๐Ÿงœ๐Ÿฝโ€โ™‚๐Ÿงœ๐Ÿพโ€โ™‚๏ธ๐Ÿงœ๐Ÿพโ€โ™‚๐Ÿงœ๐Ÿฟโ€โ™‚๏ธ๐Ÿงœ๐Ÿฟโ€โ™‚๐Ÿง๐Ÿง๐Ÿป๐Ÿง๐Ÿผ๐Ÿง๐Ÿฝ๐Ÿง๐Ÿพ๐Ÿง๐Ÿฟ๐Ÿงโ€โ™€๏ธ๐Ÿงโ€โ™€๐Ÿง๐Ÿปโ€โ™€๏ธ๐Ÿง๐Ÿปโ€โ™€๐Ÿง๐Ÿผโ€โ™€๏ธ๐Ÿง๐Ÿผโ€โ™€๐Ÿง๐Ÿฝโ€โ™€๏ธ๐Ÿง๐Ÿฝโ€โ™€๐Ÿง๐Ÿพโ€โ™€๏ธ๐Ÿง๐Ÿพโ€โ™€๐Ÿง๐Ÿฟโ€โ™€๏ธ๐Ÿง๐Ÿฟโ€โ™€๐Ÿงโ€โ™‚๏ธ๐Ÿงโ€โ™‚๐Ÿง๐Ÿปโ€โ™‚๏ธ๐Ÿง๐Ÿปโ€โ™‚๐Ÿง๐Ÿผโ€โ™‚๏ธ๐Ÿง๐Ÿผโ€โ™‚๐Ÿง๐Ÿฝโ€โ™‚๏ธ๐Ÿง๐Ÿฝโ€โ™‚๐Ÿง๐Ÿพโ€โ™‚๏ธ๐Ÿง๐Ÿพโ€โ™‚๐Ÿง๐Ÿฟโ€โ™‚๏ธ๐Ÿง๐Ÿฟโ€โ™‚๐Ÿงž๐Ÿงžโ€โ™€๏ธ๐Ÿงžโ€โ™€๐Ÿงžโ€โ™‚๏ธ๐Ÿงžโ€โ™‚๐ŸงŸ๐ŸงŸโ€โ™€๏ธ๐ŸงŸโ€โ™€๐ŸงŸโ€โ™‚๏ธ๐ŸงŸโ€โ™‚๐Ÿ™๐Ÿ™๐Ÿป๐Ÿ™๐Ÿผ๐Ÿ™๐Ÿฝ๐Ÿ™๐Ÿพ๐Ÿ™๐Ÿฟ๐Ÿ™โ€โ™‚๏ธ๐Ÿ™โ€โ™‚๐Ÿ™๐Ÿปโ€โ™‚๏ธ๐Ÿ™๐Ÿปโ€โ™‚๐Ÿ™๐Ÿผโ€โ™‚๏ธ๐Ÿ™๐Ÿผโ€โ™‚๐Ÿ™๐Ÿฝโ€โ™‚๏ธ๐Ÿ™๐Ÿฝโ€โ™‚๐Ÿ™๐Ÿพโ€โ™‚๏ธ๐Ÿ™๐Ÿพโ€โ™‚๐Ÿ™๐Ÿฟโ€โ™‚๏ธ๐Ÿ™๐Ÿฟโ€โ™‚๐Ÿ™โ€โ™€๏ธ๐Ÿ™โ€โ™€๐Ÿ™๐Ÿปโ€โ™€๏ธ๐Ÿ™๐Ÿปโ€โ™€๐Ÿ™๐Ÿผโ€โ™€๏ธ๐Ÿ™๐Ÿผโ€โ™€๐Ÿ™๐Ÿฝโ€โ™€๏ธ๐Ÿ™๐Ÿฝโ€โ™€๐Ÿ™๐Ÿพโ€โ™€๏ธ๐Ÿ™๐Ÿพโ€โ™€๐Ÿ™๐Ÿฟโ€โ™€๏ธ๐Ÿ™๐Ÿฟโ€โ™€๐Ÿ™Ž๐Ÿ™Ž๐Ÿป๐Ÿ™Ž๐Ÿผ๐Ÿ™Ž๐Ÿฝ๐Ÿ™Ž๐Ÿพ๐Ÿ™Ž๐Ÿฟ๐Ÿ™Žโ€โ™‚๏ธ๐Ÿ™Žโ€โ™‚๐Ÿ™Ž๐Ÿปโ€โ™‚๏ธ๐Ÿ™Ž๐Ÿปโ€โ™‚๐Ÿ™Ž๐Ÿผโ€โ™‚๏ธ๐Ÿ™Ž๐Ÿผโ€โ™‚๐Ÿ™Ž๐Ÿฝโ€โ™‚๏ธ๐Ÿ™Ž๐Ÿฝโ€โ™‚๐Ÿ™Ž๐Ÿพโ€โ™‚๏ธ๐Ÿ™Ž๐Ÿพโ€โ™‚๐Ÿ™Ž๐Ÿฟโ€โ™‚๏ธ๐Ÿ™Ž๐Ÿฟโ€โ™‚๐Ÿ™Žโ€โ™€๏ธ๐Ÿ™Žโ€โ™€๐Ÿ™Ž๐Ÿปโ€โ™€๏ธ๐Ÿ™Ž๐Ÿปโ€โ™€๐Ÿ™Ž๐Ÿผโ€โ™€๏ธ๐Ÿ™Ž๐Ÿผโ€โ™€๐Ÿ™Ž๐Ÿฝโ€โ™€๏ธ๐Ÿ™Ž๐Ÿฝโ€โ™€๐Ÿ™Ž๐Ÿพโ€โ™€๏ธ๐Ÿ™Ž๐Ÿพโ€โ™€๐Ÿ™Ž๐Ÿฟโ€โ™€๏ธ๐Ÿ™Ž๐Ÿฟโ€โ™€๐Ÿ™…๐Ÿ™…๐Ÿป๐Ÿ™…๐Ÿผ๐Ÿ™…๐Ÿฝ๐Ÿ™…๐Ÿพ๐Ÿ™…๐Ÿฟ๐Ÿ™…โ€โ™‚๏ธ๐Ÿ™…โ€โ™‚๐Ÿ™…๐Ÿปโ€โ™‚๏ธ๐Ÿ™…๐Ÿปโ€โ™‚๐Ÿ™…๐Ÿผโ€โ™‚๏ธ๐Ÿ™…๐Ÿผโ€โ™‚๐Ÿ™…๐Ÿฝโ€โ™‚๏ธ๐Ÿ™…๐Ÿฝโ€โ™‚๐Ÿ™…๐Ÿพโ€โ™‚๏ธ๐Ÿ™…๐Ÿพโ€โ™‚๐Ÿ™…๐Ÿฟโ€โ™‚๏ธ๐Ÿ™…๐Ÿฟโ€โ™‚๐Ÿ™…โ€โ™€๏ธ๐Ÿ™…โ€โ™€๐Ÿ™…๐Ÿปโ€โ™€๏ธ๐Ÿ™…๐Ÿปโ€โ™€๐Ÿ™…๐Ÿผโ€โ™€๏ธ๐Ÿ™…๐Ÿผโ€โ™€๐Ÿ™…๐Ÿฝโ€โ™€๏ธ๐Ÿ™…๐Ÿฝโ€โ™€๐Ÿ™…๐Ÿพโ€โ™€๏ธ๐Ÿ™…๐Ÿพโ€โ™€๐Ÿ™…๐Ÿฟโ€โ™€๏ธ๐Ÿ™…๐Ÿฟโ€โ™€๐Ÿ™†๐Ÿ™†๐Ÿป๐Ÿ™†๐Ÿผ๐Ÿ™†๐Ÿฝ๐Ÿ™†๐Ÿพ๐Ÿ™†๐Ÿฟ๐Ÿ™†โ€โ™‚๏ธ๐Ÿ™†โ€โ™‚๐Ÿ™†๐Ÿปโ€โ™‚๏ธ๐Ÿ™†๐Ÿปโ€โ™‚๐Ÿ™†๐Ÿผโ€โ™‚๏ธ๐Ÿ™†๐Ÿผโ€โ™‚๐Ÿ™†๐Ÿฝโ€โ™‚๏ธ๐Ÿ™†๐Ÿฝโ€โ™‚๐Ÿ™†๐Ÿพโ€โ™‚๏ธ๐Ÿ™†๐Ÿพโ€โ™‚๐Ÿ™†๐Ÿฟโ€โ™‚๏ธ๐Ÿ™†๐Ÿฟโ€โ™‚๐Ÿ™†โ€โ™€๏ธ๐Ÿ™†โ€โ™€๐Ÿ™†๐Ÿปโ€โ™€๏ธ๐Ÿ™†๐Ÿปโ€โ™€๐Ÿ™†๐Ÿผโ€โ™€๏ธ๐Ÿ™†๐Ÿผโ€โ™€๐Ÿ™†๐Ÿฝโ€โ™€๏ธ๐Ÿ™†๐Ÿฝโ€โ™€๐Ÿ™†๐Ÿพโ€โ™€๏ธ๐Ÿ™†๐Ÿพโ€โ™€๐Ÿ™†๐Ÿฟโ€โ™€๏ธ๐Ÿ™†๐Ÿฟโ€โ™€๐Ÿ’๐Ÿ’๐Ÿป๐Ÿ’๐Ÿผ๐Ÿ’๐Ÿฝ๐Ÿ’๐Ÿพ๐Ÿ’๐Ÿฟ๐Ÿ’โ€โ™‚๏ธ๐Ÿ’โ€โ™‚๐Ÿ’๐Ÿปโ€โ™‚๏ธ๐Ÿ’๐Ÿปโ€โ™‚๐Ÿ’๐Ÿผโ€โ™‚๏ธ๐Ÿ’๐Ÿผโ€โ™‚๐Ÿ’๐Ÿฝโ€โ™‚๏ธ๐Ÿ’๐Ÿฝโ€โ™‚๐Ÿ’๐Ÿพโ€โ™‚๏ธ๐Ÿ’๐Ÿพโ€โ™‚๐Ÿ’๐Ÿฟโ€โ™‚๏ธ๐Ÿ’๐Ÿฟโ€โ™‚๐Ÿ’โ€โ™€๏ธ๐Ÿ’โ€โ™€๐Ÿ’๐Ÿปโ€โ™€๏ธ๐Ÿ’๐Ÿปโ€โ™€๐Ÿ’๐Ÿผโ€โ™€๏ธ๐Ÿ’๐Ÿผโ€โ™€๐Ÿ’๐Ÿฝโ€โ™€๏ธ๐Ÿ’๐Ÿฝโ€โ™€๐Ÿ’๐Ÿพโ€โ™€๏ธ๐Ÿ’๐Ÿพโ€โ™€๐Ÿ’๐Ÿฟโ€โ™€๏ธ๐Ÿ’๐Ÿฟโ€โ™€๐Ÿ™‹๐Ÿ™‹๐Ÿป๐Ÿ™‹๐Ÿผ๐Ÿ™‹๐Ÿฝ๐Ÿ™‹๐Ÿพ๐Ÿ™‹๐Ÿฟ๐Ÿ™‹โ€โ™‚๏ธ๐Ÿ™‹โ€โ™‚๐Ÿ™‹๐Ÿปโ€โ™‚๏ธ๐Ÿ™‹๐Ÿปโ€โ™‚๐Ÿ™‹๐Ÿผโ€โ™‚๏ธ๐Ÿ™‹๐Ÿผโ€โ™‚๐Ÿ™‹๐Ÿฝโ€โ™‚๏ธ๐Ÿ™‹๐Ÿฝโ€โ™‚๐Ÿ™‹๐Ÿพโ€โ™‚๏ธ๐Ÿ™‹๐Ÿพโ€โ™‚๐Ÿ™‹๐Ÿฟโ€โ™‚๏ธ๐Ÿ™‹๐Ÿฟโ€โ™‚๐Ÿ™‹โ€โ™€๏ธ๐Ÿ™‹โ€โ™€๐Ÿ™‹๐Ÿปโ€โ™€๏ธ๐Ÿ™‹๐Ÿปโ€โ™€๐Ÿ™‹๐Ÿผโ€โ™€๏ธ๐Ÿ™‹๐Ÿผโ€โ™€๐Ÿ™‹๐Ÿฝโ€โ™€๏ธ๐Ÿ™‹๐Ÿฝโ€โ™€๐Ÿ™‹๐Ÿพโ€โ™€๏ธ๐Ÿ™‹๐Ÿพโ€โ™€๐Ÿ™‹๐Ÿฟโ€โ™€๏ธ๐Ÿ™‹๐Ÿฟโ€โ™€๐Ÿ™‡๐Ÿ™‡๐Ÿป๐Ÿ™‡๐Ÿผ๐Ÿ™‡๐Ÿฝ๐Ÿ™‡๐Ÿพ๐Ÿ™‡๐Ÿฟ๐Ÿ™‡โ€โ™‚๏ธ๐Ÿ™‡โ€โ™‚๐Ÿ™‡๐Ÿปโ€โ™‚๏ธ๐Ÿ™‡๐Ÿปโ€โ™‚๐Ÿ™‡๐Ÿผโ€โ™‚๏ธ๐Ÿ™‡๐Ÿผโ€โ™‚๐Ÿ™‡๐Ÿฝโ€โ™‚๏ธ๐Ÿ™‡๐Ÿฝโ€โ™‚๐Ÿ™‡๐Ÿพโ€โ™‚๏ธ๐Ÿ™‡๐Ÿพโ€โ™‚๐Ÿ™‡๐Ÿฟโ€โ™‚๏ธ๐Ÿ™‡๐Ÿฟโ€โ™‚๐Ÿ™‡โ€โ™€๏ธ๐Ÿ™‡โ€โ™€๐Ÿ™‡๐Ÿปโ€โ™€๏ธ๐Ÿ™‡๐Ÿปโ€โ™€๐Ÿ™‡๐Ÿผโ€โ™€๏ธ๐Ÿ™‡๐Ÿผโ€โ™€๐Ÿ™‡๐Ÿฝโ€โ™€๏ธ๐Ÿ™‡๐Ÿฝโ€โ™€๐Ÿ™‡๐Ÿพโ€โ™€๏ธ๐Ÿ™‡๐Ÿพโ€โ™€๐Ÿ™‡๐Ÿฟโ€โ™€๏ธ๐Ÿ™‡๐Ÿฟโ€โ™€๐Ÿคฆ๐Ÿคฆ๐Ÿป๐Ÿคฆ๐Ÿผ๐Ÿคฆ๐Ÿฝ๐Ÿคฆ๐Ÿพ๐Ÿคฆ๐Ÿฟ๐Ÿคฆโ€โ™‚๏ธ๐Ÿคฆโ€โ™‚๐Ÿคฆ๐Ÿปโ€โ™‚๏ธ๐Ÿคฆ๐Ÿปโ€โ™‚๐Ÿคฆ๐Ÿผโ€โ™‚๏ธ๐Ÿคฆ๐Ÿผโ€โ™‚๐Ÿคฆ๐Ÿฝโ€โ™‚๏ธ๐Ÿคฆ๐Ÿฝโ€โ™‚๐Ÿคฆ๐Ÿพโ€โ™‚๏ธ๐Ÿคฆ๐Ÿพโ€โ™‚๐Ÿคฆ๐Ÿฟโ€โ™‚๏ธ๐Ÿคฆ๐Ÿฟโ€โ™‚๐Ÿคฆโ€โ™€๏ธ๐Ÿคฆโ€โ™€๐Ÿคฆ๐Ÿปโ€โ™€๏ธ๐Ÿคฆ๐Ÿปโ€โ™€๐Ÿคฆ๐Ÿผโ€โ™€๏ธ๐Ÿคฆ๐Ÿผโ€โ™€๐Ÿคฆ๐Ÿฝโ€โ™€๏ธ๐Ÿคฆ๐Ÿฝโ€โ™€๐Ÿคฆ๐Ÿพโ€โ™€๏ธ๐Ÿคฆ๐Ÿพโ€โ™€๐Ÿคฆ๐Ÿฟโ€โ™€๏ธ๐Ÿคฆ๐Ÿฟโ€โ™€๐Ÿคท๐Ÿคท๐Ÿป๐Ÿคท๐Ÿผ๐Ÿคท๐Ÿฝ๐Ÿคท๐Ÿพ๐Ÿคท๐Ÿฟ๐Ÿคทโ€โ™‚๏ธ๐Ÿคทโ€โ™‚๐Ÿคท๐Ÿปโ€โ™‚๏ธ๐Ÿคท๐Ÿปโ€โ™‚๐Ÿคท๐Ÿผโ€โ™‚๏ธ๐Ÿคท๐Ÿผโ€โ™‚๐Ÿคท๐Ÿฝโ€โ™‚๏ธ๐Ÿคท๐Ÿฝโ€โ™‚๐Ÿคท๐Ÿพโ€โ™‚๏ธ๐Ÿคท๐Ÿพโ€โ™‚๐Ÿคท๐Ÿฟโ€โ™‚๏ธ๐Ÿคท๐Ÿฟโ€โ™‚๐Ÿคทโ€โ™€๏ธ๐Ÿคทโ€โ™€๐Ÿคท๐Ÿปโ€โ™€๏ธ๐Ÿคท๐Ÿปโ€โ™€๐Ÿคท๐Ÿผโ€โ™€๏ธ๐Ÿคท๐Ÿผโ€โ™€๐Ÿคท๐Ÿฝโ€โ™€๏ธ๐Ÿคท๐Ÿฝโ€โ™€๐Ÿคท๐Ÿพโ€โ™€๏ธ๐Ÿคท๐Ÿพโ€โ™€๐Ÿคท๐Ÿฟโ€โ™€๏ธ๐Ÿคท๐Ÿฟโ€โ™€๐Ÿ’†๐Ÿ’†๐Ÿป๐Ÿ’†๐Ÿผ๐Ÿ’†๐Ÿฝ๐Ÿ’†๐Ÿพ๐Ÿ’†๐Ÿฟ๐Ÿ’†โ€โ™‚๏ธ๐Ÿ’†โ€โ™‚๐Ÿ’†๐Ÿปโ€โ™‚๏ธ๐Ÿ’†๐Ÿปโ€โ™‚๐Ÿ’†๐Ÿผโ€โ™‚๏ธ๐Ÿ’†๐Ÿผโ€โ™‚๐Ÿ’†๐Ÿฝโ€โ™‚๏ธ๐Ÿ’†๐Ÿฝโ€โ™‚๐Ÿ’†๐Ÿพโ€โ™‚๏ธ๐Ÿ’†๐Ÿพโ€โ™‚๐Ÿ’†๐Ÿฟโ€โ™‚๏ธ๐Ÿ’†๐Ÿฟโ€โ™‚๐Ÿ’†โ€โ™€๏ธ๐Ÿ’†โ€โ™€๐Ÿ’†๐Ÿปโ€โ™€๏ธ๐Ÿ’†๐Ÿปโ€โ™€๐Ÿ’†๐Ÿผโ€โ™€๏ธ๐Ÿ’†๐Ÿผโ€โ™€๐Ÿ’†๐Ÿฝโ€โ™€๏ธ๐Ÿ’†๐Ÿฝโ€โ™€๐Ÿ’†๐Ÿพโ€โ™€๏ธ๐Ÿ’†๐Ÿพโ€โ™€๐Ÿ’†๐Ÿฟโ€โ™€๏ธ๐Ÿ’†๐Ÿฟโ€โ™€๐Ÿ’‡๐Ÿ’‡๐Ÿป๐Ÿ’‡๐Ÿผ๐Ÿ’‡๐Ÿฝ๐Ÿ’‡๐Ÿพ๐Ÿ’‡๐Ÿฟ๐Ÿ’‡โ€โ™‚๏ธ๐Ÿ’‡โ€โ™‚๐Ÿ’‡๐Ÿปโ€โ™‚๏ธ๐Ÿ’‡๐Ÿปโ€โ™‚๐Ÿ’‡๐Ÿผโ€โ™‚๏ธ๐Ÿ’‡๐Ÿผโ€โ™‚๐Ÿ’‡๐Ÿฝโ€โ™‚๏ธ๐Ÿ’‡๐Ÿฝโ€โ™‚๐Ÿ’‡๐Ÿพโ€โ™‚๏ธ๐Ÿ’‡๐Ÿพโ€โ™‚๐Ÿ’‡๐Ÿฟโ€โ™‚๏ธ๐Ÿ’‡๐Ÿฟโ€โ™‚๐Ÿ’‡โ€โ™€๏ธ๐Ÿ’‡โ€โ™€๐Ÿ’‡๐Ÿปโ€โ™€๏ธ๐Ÿ’‡๐Ÿปโ€โ™€๐Ÿ’‡๐Ÿผโ€โ™€๏ธ๐Ÿ’‡๐Ÿผโ€โ™€๐Ÿ’‡๐Ÿฝโ€โ™€๏ธ๐Ÿ’‡๐Ÿฝโ€โ™€๐Ÿ’‡๐Ÿพโ€โ™€๏ธ๐Ÿ’‡๐Ÿพโ€โ™€๐Ÿ’‡๐Ÿฟโ€โ™€๏ธ๐Ÿ’‡๐Ÿฟโ€โ™€๐Ÿšถ๐Ÿšถ๐Ÿป๐Ÿšถ๐Ÿผ๐Ÿšถ๐Ÿฝ๐Ÿšถ๐Ÿพ๐Ÿšถ๐Ÿฟ๐Ÿšถโ€โ™‚๏ธ๐Ÿšถโ€โ™‚๐Ÿšถ๐Ÿปโ€โ™‚๏ธ๐Ÿšถ๐Ÿปโ€โ™‚๐Ÿšถ๐Ÿผโ€โ™‚๏ธ๐Ÿšถ๐Ÿผโ€โ™‚๐Ÿšถ๐Ÿฝโ€โ™‚๏ธ๐Ÿšถ๐Ÿฝโ€โ™‚๐Ÿšถ๐Ÿพโ€โ™‚๏ธ๐Ÿšถ๐Ÿพโ€โ™‚๐Ÿšถ๐Ÿฟโ€โ™‚๏ธ๐Ÿšถ๐Ÿฟโ€โ™‚๐Ÿšถโ€โ™€๏ธ๐Ÿšถโ€โ™€๐Ÿšถ๐Ÿปโ€โ™€๏ธ๐Ÿšถ๐Ÿปโ€โ™€๐Ÿšถ๐Ÿผโ€โ™€๏ธ๐Ÿšถ๐Ÿผโ€โ™€๐Ÿšถ๐Ÿฝโ€โ™€๏ธ๐Ÿšถ๐Ÿฝโ€โ™€๐Ÿšถ๐Ÿพโ€โ™€๏ธ๐Ÿšถ๐Ÿพโ€โ™€๐Ÿšถ๐Ÿฟโ€โ™€๏ธ๐Ÿšถ๐Ÿฟโ€โ™€๐Ÿƒ๐Ÿƒ๐Ÿป๐Ÿƒ๐Ÿผ๐Ÿƒ๐Ÿฝ๐Ÿƒ๐Ÿพ๐Ÿƒ๐Ÿฟ๐Ÿƒโ€โ™‚๏ธ๐Ÿƒโ€โ™‚๐Ÿƒ๐Ÿปโ€โ™‚๏ธ๐Ÿƒ๐Ÿปโ€โ™‚๐Ÿƒ๐Ÿผโ€โ™‚๏ธ๐Ÿƒ๐Ÿผโ€โ™‚๐Ÿƒ๐Ÿฝโ€โ™‚๏ธ๐Ÿƒ๐Ÿฝโ€โ™‚๐Ÿƒ๐Ÿพโ€โ™‚๏ธ๐Ÿƒ๐Ÿพโ€โ™‚๐Ÿƒ๐Ÿฟโ€โ™‚๏ธ๐Ÿƒ๐Ÿฟโ€โ™‚๐Ÿƒโ€โ™€๏ธ๐Ÿƒโ€โ™€๐Ÿƒ๐Ÿปโ€โ™€๏ธ๐Ÿƒ๐Ÿปโ€โ™€๐Ÿƒ๐Ÿผโ€โ™€๏ธ๐Ÿƒ๐Ÿผโ€โ™€๐Ÿƒ๐Ÿฝโ€โ™€๏ธ๐Ÿƒ๐Ÿฝโ€โ™€๐Ÿƒ๐Ÿพโ€โ™€๏ธ๐Ÿƒ๐Ÿพโ€โ™€๐Ÿƒ๐Ÿฟโ€โ™€๏ธ๐Ÿƒ๐Ÿฟโ€โ™€๐Ÿ’ƒ๐Ÿ’ƒ๐Ÿป๐Ÿ’ƒ๐Ÿผ๐Ÿ’ƒ๐Ÿฝ๐Ÿ’ƒ๐Ÿพ๐Ÿ’ƒ๐Ÿฟ๐Ÿ•บ๐Ÿ•บ๐Ÿป๐Ÿ•บ๐Ÿผ๐Ÿ•บ๐Ÿฝ๐Ÿ•บ๐Ÿพ๐Ÿ•บ๐Ÿฟ๐Ÿ‘ฏ๐Ÿ‘ฏโ€โ™‚๏ธ๐Ÿ‘ฏโ€โ™‚๐Ÿ‘ฏโ€โ™€๏ธ๐Ÿ‘ฏโ€โ™€๐Ÿง–๐Ÿง–๐Ÿป๐Ÿง–๐Ÿผ๐Ÿง–๐Ÿฝ๐Ÿง–๐Ÿพ๐Ÿง–๐Ÿฟ๐Ÿง–โ€โ™€๏ธ๐Ÿง–โ€โ™€๐Ÿง–๐Ÿปโ€โ™€๏ธ๐Ÿง–๐Ÿปโ€โ™€๐Ÿง–๐Ÿผโ€โ™€๏ธ๐Ÿง–๐Ÿผโ€โ™€๐Ÿง–๐Ÿฝโ€โ™€๏ธ๐Ÿง–๐Ÿฝโ€โ™€๐Ÿง–๐Ÿพโ€โ™€๏ธ๐Ÿง–๐Ÿพโ€โ™€๐Ÿง–๐Ÿฟโ€โ™€๏ธ๐Ÿง–๐Ÿฟโ€โ™€๐Ÿง–โ€โ™‚๏ธ๐Ÿง–โ€โ™‚๐Ÿง–๐Ÿปโ€โ™‚๏ธ๐Ÿง–๐Ÿปโ€โ™‚๐Ÿง–๐Ÿผโ€โ™‚๏ธ๐Ÿง–๐Ÿผโ€โ™‚๐Ÿง–๐Ÿฝโ€โ™‚๏ธ๐Ÿง–๐Ÿฝโ€โ™‚๐Ÿง–๐Ÿพโ€โ™‚๏ธ๐Ÿง–๐Ÿพโ€โ™‚๐Ÿง–๐Ÿฟโ€โ™‚๏ธ๐Ÿง–๐Ÿฟโ€โ™‚๐Ÿง—๐Ÿง—๐Ÿป๐Ÿง—๐Ÿผ๐Ÿง—๐Ÿฝ๐Ÿง—๐Ÿพ๐Ÿง—๐Ÿฟ๐Ÿง—โ€โ™€๏ธ๐Ÿง—โ€โ™€๐Ÿง—๐Ÿปโ€โ™€๏ธ๐Ÿง—๐Ÿปโ€โ™€๐Ÿง—๐Ÿผโ€โ™€๏ธ๐Ÿง—๐Ÿผโ€โ™€๐Ÿง—๐Ÿฝโ€โ™€๏ธ๐Ÿง—๐Ÿฝโ€โ™€๐Ÿง—๐Ÿพโ€โ™€๏ธ๐Ÿง—๐Ÿพโ€โ™€๐Ÿง—๐Ÿฟโ€โ™€๏ธ๐Ÿง—๐Ÿฟโ€โ™€๐Ÿง—โ€โ™‚๏ธ๐Ÿง—โ€โ™‚๐Ÿง—๐Ÿปโ€โ™‚๏ธ๐Ÿง—๐Ÿปโ€โ™‚๐Ÿง—๐Ÿผโ€โ™‚๏ธ๐Ÿง—๐Ÿผโ€โ™‚๐Ÿง—๐Ÿฝโ€โ™‚๏ธ๐Ÿง—๐Ÿฝโ€โ™‚๐Ÿง—๐Ÿพโ€โ™‚๏ธ๐Ÿง—๐Ÿพโ€โ™‚๐Ÿง—๐Ÿฟโ€โ™‚๏ธ๐Ÿง—๐Ÿฟโ€โ™‚๐Ÿง˜๐Ÿง˜๐Ÿป๐Ÿง˜๐Ÿผ๐Ÿง˜๐Ÿฝ๐Ÿง˜๐Ÿพ๐Ÿง˜๐Ÿฟ๐Ÿง˜โ€โ™€๏ธ๐Ÿง˜โ€โ™€๐Ÿง˜๐Ÿปโ€โ™€๏ธ๐Ÿง˜๐Ÿปโ€โ™€๐Ÿง˜๐Ÿผโ€โ™€๏ธ๐Ÿง˜๐Ÿผโ€โ™€๐Ÿง˜๐Ÿฝโ€โ™€๏ธ๐Ÿง˜๐Ÿฝโ€โ™€๐Ÿง˜๐Ÿพโ€โ™€๏ธ๐Ÿง˜๐Ÿพโ€โ™€๐Ÿง˜๐Ÿฟโ€โ™€๏ธ๐Ÿง˜๐Ÿฟโ€โ™€๐Ÿง˜โ€โ™‚๏ธ๐Ÿง˜โ€โ™‚๐Ÿง˜๐Ÿปโ€โ™‚๏ธ๐Ÿง˜๐Ÿปโ€โ™‚๐Ÿง˜๐Ÿผโ€โ™‚๏ธ๐Ÿง˜๐Ÿผโ€โ™‚๐Ÿง˜๐Ÿฝโ€โ™‚๏ธ๐Ÿง˜๐Ÿฝโ€โ™‚๐Ÿง˜๐Ÿพโ€โ™‚๏ธ๐Ÿง˜๐Ÿพโ€โ™‚๐Ÿง˜๐Ÿฟโ€โ™‚๏ธ๐Ÿง˜๐Ÿฟโ€โ™‚๐Ÿ›€๐Ÿ›€๐Ÿป๐Ÿ›€๐Ÿผ๐Ÿ›€๐Ÿฝ๐Ÿ›€๐Ÿพ๐Ÿ›€๐Ÿฟ๐Ÿ›Œ๐Ÿ›Œ๐Ÿป๐Ÿ›Œ๐Ÿผ๐Ÿ›Œ๐Ÿฝ๐Ÿ›Œ๐Ÿพ๐Ÿ›Œ๐Ÿฟ๐Ÿ•ด๏ธ๐Ÿ•ด๐Ÿ•ด๐Ÿป๐Ÿ•ด๐Ÿผ๐Ÿ•ด๐Ÿฝ๐Ÿ•ด๐Ÿพ๐Ÿ•ด๐Ÿฟ๐Ÿ—ฃ๏ธ๐Ÿ—ฃ๐Ÿ‘ค๐Ÿ‘ฅ๐Ÿคบ๐Ÿ‡๐Ÿ‡๐Ÿป๐Ÿ‡๐Ÿผ๐Ÿ‡๐Ÿฝ๐Ÿ‡๐Ÿพ๐Ÿ‡๐Ÿฟโ›ท๏ธโ›ท๐Ÿ‚๐Ÿ‚๐Ÿป๐Ÿ‚๐Ÿผ๐Ÿ‚๐Ÿฝ๐Ÿ‚๐Ÿพ๐Ÿ‚๐Ÿฟ๐ŸŒ๏ธ๐ŸŒ๐ŸŒ๐Ÿป๐ŸŒ๐Ÿผ๐ŸŒ๐Ÿฝ๐ŸŒ๐Ÿพ๐ŸŒ๐Ÿฟ๐ŸŒ๏ธโ€โ™‚๏ธ๐ŸŒโ€โ™‚๏ธ๐ŸŒ๏ธโ€โ™‚๐ŸŒโ€โ™‚๐ŸŒ๐Ÿปโ€โ™‚๏ธ๐ŸŒ๐Ÿปโ€โ™‚๐ŸŒ๐Ÿผโ€โ™‚๏ธ๐ŸŒ๐Ÿผโ€โ™‚๐ŸŒ๐Ÿฝโ€โ™‚๏ธ๐ŸŒ๐Ÿฝโ€โ™‚๐ŸŒ๐Ÿพโ€โ™‚๏ธ๐ŸŒ๐Ÿพโ€โ™‚๐ŸŒ๐Ÿฟโ€โ™‚๏ธ๐ŸŒ๐Ÿฟโ€โ™‚๐ŸŒ๏ธโ€โ™€๏ธ๐ŸŒโ€โ™€๏ธ๐ŸŒ๏ธโ€โ™€๐ŸŒโ€โ™€๐ŸŒ๐Ÿปโ€โ™€๏ธ๐ŸŒ๐Ÿปโ€โ™€๐ŸŒ๐Ÿผโ€โ™€๏ธ๐ŸŒ๐Ÿผโ€โ™€๐ŸŒ๐Ÿฝโ€โ™€๏ธ๐ŸŒ๐Ÿฝโ€โ™€๐ŸŒ๐Ÿพโ€โ™€๏ธ๐ŸŒ๐Ÿพโ€โ™€๐ŸŒ๐Ÿฟโ€โ™€๏ธ๐ŸŒ๐Ÿฟโ€โ™€๐Ÿ„๐Ÿ„๐Ÿป๐Ÿ„๐Ÿผ๐Ÿ„๐Ÿฝ๐Ÿ„๐Ÿพ๐Ÿ„๐Ÿฟ๐Ÿ„โ€โ™‚๏ธ๐Ÿ„โ€โ™‚๐Ÿ„๐Ÿปโ€โ™‚๏ธ๐Ÿ„๐Ÿปโ€โ™‚๐Ÿ„๐Ÿผโ€โ™‚๏ธ๐Ÿ„๐Ÿผโ€โ™‚๐Ÿ„๐Ÿฝโ€โ™‚๏ธ๐Ÿ„๐Ÿฝโ€โ™‚๐Ÿ„๐Ÿพโ€โ™‚๏ธ๐Ÿ„๐Ÿพโ€โ™‚๐Ÿ„๐Ÿฟโ€โ™‚๏ธ๐Ÿ„๐Ÿฟโ€โ™‚๐Ÿ„โ€โ™€๏ธ๐Ÿ„โ€โ™€๐Ÿ„๐Ÿปโ€โ™€๏ธ๐Ÿ„๐Ÿปโ€โ™€๐Ÿ„๐Ÿผโ€โ™€๏ธ๐Ÿ„๐Ÿผโ€โ™€๐Ÿ„๐Ÿฝโ€โ™€๏ธ๐Ÿ„๐Ÿฝโ€โ™€๐Ÿ„๐Ÿพโ€โ™€๏ธ๐Ÿ„๐Ÿพโ€โ™€๐Ÿ„๐Ÿฟโ€โ™€๏ธ๐Ÿ„๐Ÿฟโ€โ™€๐Ÿšฃ๐Ÿšฃ๐Ÿป๐Ÿšฃ๐Ÿผ๐Ÿšฃ๐Ÿฝ๐Ÿšฃ๐Ÿพ๐Ÿšฃ๐Ÿฟ๐Ÿšฃโ€โ™‚๏ธ๐Ÿšฃโ€โ™‚๐Ÿšฃ๐Ÿปโ€โ™‚๏ธ๐Ÿšฃ๐Ÿปโ€โ™‚๐Ÿšฃ๐Ÿผโ€โ™‚๏ธ๐Ÿšฃ๐Ÿผโ€โ™‚๐Ÿšฃ๐Ÿฝโ€โ™‚๏ธ๐Ÿšฃ๐Ÿฝโ€โ™‚๐Ÿšฃ๐Ÿพโ€โ™‚๏ธ๐Ÿšฃ๐Ÿพโ€โ™‚๐Ÿšฃ๐Ÿฟโ€โ™‚๏ธ๐Ÿšฃ๐Ÿฟโ€โ™‚๐Ÿšฃโ€โ™€๏ธ๐Ÿšฃโ€โ™€๐Ÿšฃ๐Ÿปโ€โ™€๏ธ๐Ÿšฃ๐Ÿปโ€โ™€๐Ÿšฃ๐Ÿผโ€โ™€๏ธ๐Ÿšฃ๐Ÿผโ€โ™€๐Ÿšฃ๐Ÿฝโ€โ™€๏ธ๐Ÿšฃ๐Ÿฝโ€โ™€๐Ÿšฃ๐Ÿพโ€โ™€๏ธ๐Ÿšฃ๐Ÿพโ€โ™€๐Ÿšฃ๐Ÿฟโ€โ™€๏ธ๐Ÿšฃ๐Ÿฟโ€โ™€๐ŸŠ๐ŸŠ๐Ÿป๐ŸŠ๐Ÿผ๐ŸŠ๐Ÿฝ๐ŸŠ๐Ÿพ๐ŸŠ๐Ÿฟ๐ŸŠโ€โ™‚๏ธ๐ŸŠโ€โ™‚๐ŸŠ๐Ÿปโ€โ™‚๏ธ๐ŸŠ๐Ÿปโ€โ™‚๐ŸŠ๐Ÿผโ€โ™‚๏ธ๐ŸŠ๐Ÿผโ€โ™‚๐ŸŠ๐Ÿฝโ€โ™‚๏ธ๐ŸŠ๐Ÿฝโ€โ™‚๐ŸŠ๐Ÿพโ€โ™‚๏ธ๐ŸŠ๐Ÿพโ€โ™‚๐ŸŠ๐Ÿฟโ€โ™‚๏ธ๐ŸŠ๐Ÿฟโ€โ™‚๐ŸŠโ€โ™€๏ธ๐ŸŠโ€โ™€๐ŸŠ๐Ÿปโ€โ™€๏ธ๐ŸŠ๐Ÿปโ€โ™€๐ŸŠ๐Ÿผโ€โ™€๏ธ๐ŸŠ๐Ÿผโ€โ™€๐ŸŠ๐Ÿฝโ€โ™€๏ธ๐ŸŠ๐Ÿฝโ€โ™€๐ŸŠ๐Ÿพโ€โ™€๏ธ๐ŸŠ๐Ÿพโ€โ™€๐ŸŠ๐Ÿฟโ€โ™€๏ธ๐ŸŠ๐Ÿฟโ€โ™€โ›น๏ธโ›นโ›น๐Ÿปโ›น๐Ÿผโ›น๐Ÿฝโ›น๐Ÿพโ›น๐Ÿฟโ›น๏ธโ€โ™‚๏ธโ›นโ€โ™‚๏ธโ›น๏ธโ€โ™‚โ›นโ€โ™‚โ›น๐Ÿปโ€โ™‚๏ธโ›น๐Ÿปโ€โ™‚โ›น๐Ÿผโ€โ™‚๏ธโ›น๐Ÿผโ€โ™‚โ›น๐Ÿฝโ€โ™‚๏ธโ›น๐Ÿฝโ€โ™‚โ›น๐Ÿพโ€โ™‚๏ธโ›น๐Ÿพโ€โ™‚โ›น๐Ÿฟโ€โ™‚๏ธโ›น๐Ÿฟโ€โ™‚โ›น๏ธโ€โ™€๏ธโ›นโ€โ™€๏ธโ›น๏ธโ€โ™€โ›นโ€โ™€โ›น๐Ÿปโ€โ™€๏ธโ›น๐Ÿปโ€โ™€โ›น๐Ÿผโ€โ™€๏ธโ›น๐Ÿผโ€โ™€โ›น๐Ÿฝโ€โ™€๏ธโ›น๐Ÿฝโ€โ™€โ›น๐Ÿพโ€โ™€๏ธโ›น๐Ÿพโ€โ™€โ›น๐Ÿฟโ€โ™€๏ธโ›น๐Ÿฟโ€โ™€๐Ÿ‹๏ธ๐Ÿ‹๐Ÿ‹๐Ÿป๐Ÿ‹๐Ÿผ๐Ÿ‹๐Ÿฝ๐Ÿ‹๐Ÿพ๐Ÿ‹๐Ÿฟ๐Ÿ‹๏ธโ€โ™‚๏ธ๐Ÿ‹โ€โ™‚๏ธ๐Ÿ‹๏ธโ€โ™‚๐Ÿ‹โ€โ™‚๐Ÿ‹๐Ÿปโ€โ™‚๏ธ๐Ÿ‹๐Ÿปโ€โ™‚๐Ÿ‹๐Ÿผโ€โ™‚๏ธ๐Ÿ‹๐Ÿผโ€โ™‚๐Ÿ‹๐Ÿฝโ€โ™‚๏ธ๐Ÿ‹๐Ÿฝโ€โ™‚๐Ÿ‹๐Ÿพโ€โ™‚๏ธ๐Ÿ‹๐Ÿพโ€โ™‚๐Ÿ‹๐Ÿฟโ€โ™‚๏ธ๐Ÿ‹๐Ÿฟโ€โ™‚๐Ÿ‹๏ธโ€โ™€๏ธ๐Ÿ‹โ€โ™€๏ธ๐Ÿ‹๏ธโ€โ™€๐Ÿ‹โ€โ™€๐Ÿ‹๐Ÿปโ€โ™€๏ธ๐Ÿ‹๐Ÿปโ€โ™€๐Ÿ‹๐Ÿผโ€โ™€๏ธ๐Ÿ‹๐Ÿผโ€โ™€๐Ÿ‹๐Ÿฝโ€โ™€๏ธ๐Ÿ‹๐Ÿฝโ€โ™€๐Ÿ‹๐Ÿพโ€โ™€๏ธ๐Ÿ‹๐Ÿพโ€โ™€๐Ÿ‹๐Ÿฟโ€โ™€๏ธ๐Ÿ‹๐Ÿฟโ€โ™€๐Ÿšด๐Ÿšด๐Ÿป๐Ÿšด๐Ÿผ๐Ÿšด๐Ÿฝ๐Ÿšด๐Ÿพ๐Ÿšด๐Ÿฟ๐Ÿšดโ€โ™‚๏ธ๐Ÿšดโ€โ™‚๐Ÿšด๐Ÿปโ€โ™‚๏ธ๐Ÿšด๐Ÿปโ€โ™‚๐Ÿšด๐Ÿผโ€โ™‚๏ธ๐Ÿšด๐Ÿผโ€โ™‚๐Ÿšด๐Ÿฝโ€โ™‚๏ธ๐Ÿšด๐Ÿฝโ€โ™‚๐Ÿšด๐Ÿพโ€โ™‚๏ธ๐Ÿšด๐Ÿพโ€โ™‚๐Ÿšด๐Ÿฟโ€โ™‚๏ธ๐Ÿšด๐Ÿฟโ€โ™‚๐Ÿšดโ€โ™€๏ธ๐Ÿšดโ€โ™€๐Ÿšด๐Ÿปโ€โ™€๏ธ๐Ÿšด๐Ÿปโ€โ™€๐Ÿšด๐Ÿผโ€โ™€๏ธ๐Ÿšด๐Ÿผโ€โ™€๐Ÿšด๐Ÿฝโ€โ™€๏ธ๐Ÿšด๐Ÿฝโ€โ™€๐Ÿšด๐Ÿพโ€โ™€๏ธ๐Ÿšด๐Ÿพโ€โ™€๐Ÿšด๐Ÿฟโ€โ™€๏ธ๐Ÿšด๐Ÿฟโ€โ™€๐Ÿšต๐Ÿšต๐Ÿป๐Ÿšต๐Ÿผ๐Ÿšต๐Ÿฝ๐Ÿšต๐Ÿพ๐Ÿšต๐Ÿฟ๐Ÿšตโ€โ™‚๏ธ๐Ÿšตโ€โ™‚๐Ÿšต๐Ÿปโ€โ™‚๏ธ๐Ÿšต๐Ÿปโ€โ™‚๐Ÿšต๐Ÿผโ€โ™‚๏ธ๐Ÿšต๐Ÿผโ€โ™‚๐Ÿšต๐Ÿฝโ€โ™‚๏ธ๐Ÿšต๐Ÿฝโ€โ™‚๐Ÿšต๐Ÿพโ€โ™‚๏ธ๐Ÿšต๐Ÿพโ€โ™‚๐Ÿšต๐Ÿฟโ€โ™‚๏ธ๐Ÿšต๐Ÿฟโ€โ™‚๐Ÿšตโ€โ™€๏ธ๐Ÿšตโ€โ™€๐Ÿšต๐Ÿปโ€โ™€๏ธ๐Ÿšต๐Ÿปโ€โ™€๐Ÿšต๐Ÿผโ€โ™€๏ธ๐Ÿšต๐Ÿผโ€โ™€๐Ÿšต๐Ÿฝโ€โ™€๏ธ๐Ÿšต๐Ÿฝโ€โ™€๐Ÿšต๐Ÿพโ€โ™€๏ธ๐Ÿšต๐Ÿพโ€โ™€๐Ÿšต๐Ÿฟโ€โ™€๏ธ๐Ÿšต๐Ÿฟโ€โ™€๐ŸŽ๏ธ๐ŸŽ๐Ÿ๏ธ๐Ÿ๐Ÿคธ๐Ÿคธ๐Ÿป๐Ÿคธ๐Ÿผ๐Ÿคธ๐Ÿฝ๐Ÿคธ๐Ÿพ๐Ÿคธ๐Ÿฟ๐Ÿคธโ€โ™‚๏ธ๐Ÿคธโ€โ™‚๐Ÿคธ๐Ÿปโ€โ™‚๏ธ๐Ÿคธ๐Ÿปโ€โ™‚๐Ÿคธ๐Ÿผโ€โ™‚๏ธ๐Ÿคธ๐Ÿผโ€โ™‚๐Ÿคธ๐Ÿฝโ€โ™‚๏ธ๐Ÿคธ๐Ÿฝโ€โ™‚๐Ÿคธ๐Ÿพโ€โ™‚๏ธ๐Ÿคธ๐Ÿพโ€โ™‚๐Ÿคธ๐Ÿฟโ€โ™‚๏ธ๐Ÿคธ๐Ÿฟโ€โ™‚๐Ÿคธโ€โ™€๏ธ๐Ÿคธโ€โ™€๐Ÿคธ๐Ÿปโ€โ™€๏ธ๐Ÿคธ๐Ÿปโ€โ™€๐Ÿคธ๐Ÿผโ€โ™€๏ธ๐Ÿคธ๐Ÿผโ€โ™€๐Ÿคธ๐Ÿฝโ€โ™€๏ธ๐Ÿคธ๐Ÿฝโ€โ™€๐Ÿคธ๐Ÿพโ€โ™€๏ธ๐Ÿคธ๐Ÿพโ€โ™€๐Ÿคธ๐Ÿฟโ€โ™€๏ธ๐Ÿคธ๐Ÿฟโ€โ™€๐Ÿคผ๐Ÿคผโ€โ™‚๏ธ๐Ÿคผโ€โ™‚๐Ÿคผโ€โ™€๏ธ๐Ÿคผโ€โ™€๐Ÿคฝ๐Ÿคฝ๐Ÿป๐Ÿคฝ๐Ÿผ๐Ÿคฝ๐Ÿฝ๐Ÿคฝ๐Ÿพ๐Ÿคฝ๐Ÿฟ๐Ÿคฝโ€โ™‚๏ธ๐Ÿคฝโ€โ™‚๐Ÿคฝ๐Ÿปโ€โ™‚๏ธ๐Ÿคฝ๐Ÿปโ€โ™‚๐Ÿคฝ๐Ÿผโ€โ™‚๏ธ๐Ÿคฝ๐Ÿผโ€โ™‚๐Ÿคฝ๐Ÿฝโ€โ™‚๏ธ๐Ÿคฝ๐Ÿฝโ€โ™‚๐Ÿคฝ๐Ÿพโ€โ™‚๏ธ๐Ÿคฝ๐Ÿพโ€โ™‚๐Ÿคฝ๐Ÿฟโ€โ™‚๏ธ๐Ÿคฝ๐Ÿฟโ€โ™‚๐Ÿคฝโ€โ™€๏ธ๐Ÿคฝโ€โ™€๐Ÿคฝ๐Ÿปโ€โ™€๏ธ๐Ÿคฝ๐Ÿปโ€โ™€๐Ÿคฝ๐Ÿผโ€โ™€๏ธ๐Ÿคฝ๐Ÿผโ€โ™€๐Ÿคฝ๐Ÿฝโ€โ™€๏ธ๐Ÿคฝ๐Ÿฝโ€โ™€๐Ÿคฝ๐Ÿพโ€โ™€๏ธ๐Ÿคฝ๐Ÿพโ€โ™€๐Ÿคฝ๐Ÿฟโ€โ™€๏ธ๐Ÿคฝ๐Ÿฟโ€โ™€๐Ÿคพ๐Ÿคพ๐Ÿป๐Ÿคพ๐Ÿผ๐Ÿคพ๐Ÿฝ๐Ÿคพ๐Ÿพ๐Ÿคพ๐Ÿฟ๐Ÿคพโ€โ™‚๏ธ๐Ÿคพโ€โ™‚๐Ÿคพ๐Ÿปโ€โ™‚๏ธ๐Ÿคพ๐Ÿปโ€โ™‚๐Ÿคพ๐Ÿผโ€โ™‚๏ธ๐Ÿคพ๐Ÿผโ€โ™‚๐Ÿคพ๐Ÿฝโ€โ™‚๏ธ๐Ÿคพ๐Ÿฝโ€โ™‚๐Ÿคพ๐Ÿพโ€โ™‚๏ธ๐Ÿคพ๐Ÿพโ€โ™‚๐Ÿคพ๐Ÿฟโ€โ™‚๏ธ๐Ÿคพ๐Ÿฟโ€โ™‚๐Ÿคพโ€โ™€๏ธ๐Ÿคพโ€โ™€๐Ÿคพ๐Ÿปโ€โ™€๏ธ๐Ÿคพ๐Ÿปโ€โ™€๐Ÿคพ๐Ÿผโ€โ™€๏ธ๐Ÿคพ๐Ÿผโ€โ™€๐Ÿคพ๐Ÿฝโ€โ™€๏ธ๐Ÿคพ๐Ÿฝโ€โ™€๐Ÿคพ๐Ÿพโ€โ™€๏ธ๐Ÿคพ๐Ÿพโ€โ™€๐Ÿคพ๐Ÿฟโ€โ™€๏ธ๐Ÿคพ๐Ÿฟโ€โ™€๐Ÿคน๐Ÿคน๐Ÿป๐Ÿคน๐Ÿผ๐Ÿคน๐Ÿฝ๐Ÿคน๐Ÿพ๐Ÿคน๐Ÿฟ๐Ÿคนโ€โ™‚๏ธ๐Ÿคนโ€โ™‚๐Ÿคน๐Ÿปโ€โ™‚๏ธ๐Ÿคน๐Ÿปโ€โ™‚๐Ÿคน๐Ÿผโ€โ™‚๏ธ๐Ÿคน๐Ÿผโ€โ™‚๐Ÿคน๐Ÿฝโ€โ™‚๏ธ๐Ÿคน๐Ÿฝโ€โ™‚๐Ÿคน๐Ÿพโ€โ™‚๏ธ๐Ÿคน๐Ÿพโ€โ™‚๐Ÿคน๐Ÿฟโ€โ™‚๏ธ๐Ÿคน๐Ÿฟโ€โ™‚๐Ÿคนโ€โ™€๏ธ๐Ÿคนโ€โ™€๐Ÿคน๐Ÿปโ€โ™€๏ธ๐Ÿคน๐Ÿปโ€โ™€๐Ÿคน๐Ÿผโ€โ™€๏ธ๐Ÿคน๐Ÿผโ€โ™€๐Ÿคน๐Ÿฝโ€โ™€๏ธ๐Ÿคน๐Ÿฝโ€โ™€๐Ÿคน๐Ÿพโ€โ™€๏ธ๐Ÿคน๐Ÿพโ€โ™€๐Ÿคน๐Ÿฟโ€โ™€๏ธ๐Ÿคน๐Ÿฟโ€โ™€๐Ÿ‘ซ๐Ÿ‘ฌ๐Ÿ‘ญ๐Ÿ’๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ๐Ÿ‘ฉโ€โคโ€๐Ÿ’‹โ€๐Ÿ‘จ๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ๐Ÿ‘จโ€โคโ€๐Ÿ’‹โ€๐Ÿ‘จ๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘ฉ๐Ÿ‘ฉโ€โคโ€๐Ÿ’‹โ€๐Ÿ‘ฉ๐Ÿ’‘๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘จ๐Ÿ‘ฉโ€โคโ€๐Ÿ‘จ๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ๐Ÿ‘จโ€โคโ€๐Ÿ‘จ๐Ÿ‘ฉโ€โค๏ธโ€๐Ÿ‘ฉ๐Ÿ‘ฉโ€โคโ€๐Ÿ‘ฉ๐Ÿ‘ช๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ง๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘ง๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿ‘ฉโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘ง๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง๐Ÿคณ๐Ÿคณ๐Ÿป๐Ÿคณ๐Ÿผ๐Ÿคณ๐Ÿฝ๐Ÿคณ๐Ÿพ๐Ÿคณ๐Ÿฟ๐Ÿ’ช๐Ÿ’ช๐Ÿป๐Ÿ’ช๐Ÿผ๐Ÿ’ช๐Ÿฝ๐Ÿ’ช๐Ÿพ๐Ÿ’ช๐Ÿฟ๐Ÿฆต๐Ÿฆต๐Ÿป๐Ÿฆต๐Ÿผ๐Ÿฆต๐Ÿฝ๐Ÿฆต๐Ÿพ๐Ÿฆต๐Ÿฟ๐Ÿฆถ๐Ÿฆถ๐Ÿป๐Ÿฆถ๐Ÿผ๐Ÿฆถ๐Ÿฝ๐Ÿฆถ๐Ÿพ๐Ÿฆถ๐Ÿฟ๐Ÿ‘ˆ๐Ÿ‘ˆ๐Ÿป๐Ÿ‘ˆ๐Ÿผ๐Ÿ‘ˆ๐Ÿฝ๐Ÿ‘ˆ๐Ÿพ๐Ÿ‘ˆ๐Ÿฟ๐Ÿ‘‰๐Ÿ‘‰๐Ÿป๐Ÿ‘‰๐Ÿผ๐Ÿ‘‰๐Ÿฝ๐Ÿ‘‰๐Ÿพ๐Ÿ‘‰๐Ÿฟโ˜๏ธโ˜โ˜๐Ÿปโ˜๐Ÿผโ˜๐Ÿฝโ˜๐Ÿพโ˜๐Ÿฟ๐Ÿ‘†๐Ÿ‘†๐Ÿป๐Ÿ‘†๐Ÿผ๐Ÿ‘†๐Ÿฝ๐Ÿ‘†๐Ÿพ๐Ÿ‘†๐Ÿฟ๐Ÿ–•๐Ÿ–•๐Ÿป๐Ÿ–•๐Ÿผ๐Ÿ–•๐Ÿฝ๐Ÿ–•๐Ÿพ๐Ÿ–•๐Ÿฟ๐Ÿ‘‡๐Ÿ‘‡๐Ÿป๐Ÿ‘‡๐Ÿผ๐Ÿ‘‡๐Ÿฝ๐Ÿ‘‡๐Ÿพ๐Ÿ‘‡๐ŸฟโœŒ๏ธโœŒโœŒ๐ŸปโœŒ๐ŸผโœŒ๐ŸฝโœŒ๐ŸพโœŒ๐Ÿฟ๐Ÿคž๐Ÿคž๐Ÿป๐Ÿคž๐Ÿผ๐Ÿคž๐Ÿฝ๐Ÿคž๐Ÿพ๐Ÿคž๐Ÿฟ๐Ÿ––๐Ÿ––๐Ÿป๐Ÿ––๐Ÿผ๐Ÿ––๐Ÿฝ๐Ÿ––๐Ÿพ๐Ÿ––๐Ÿฟ๐Ÿค˜๐Ÿค˜๐Ÿป๐Ÿค˜๐Ÿผ๐Ÿค˜๐Ÿฝ๐Ÿค˜๐Ÿพ๐Ÿค˜๐Ÿฟ๐Ÿค™๐Ÿค™๐Ÿป๐Ÿค™๐Ÿผ๐Ÿค™๐Ÿฝ๐Ÿค™๐Ÿพ๐Ÿค™๐Ÿฟ๐Ÿ–๏ธ๐Ÿ–๐Ÿ–๐Ÿป๐Ÿ–๐Ÿผ๐Ÿ–๐Ÿฝ๐Ÿ–๐Ÿพ๐Ÿ–๐Ÿฟโœ‹โœ‹๐Ÿปโœ‹๐Ÿผโœ‹๐Ÿฝโœ‹๐Ÿพโœ‹๐Ÿฟ๐Ÿ‘Œ๐Ÿ‘Œ๐Ÿป๐Ÿ‘Œ๐Ÿผ๐Ÿ‘Œ๐Ÿฝ๐Ÿ‘Œ๐Ÿพ๐Ÿ‘Œ๐Ÿฟ๐Ÿ‘๐Ÿ‘๐Ÿป๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿฝ๐Ÿ‘๐Ÿพ๐Ÿ‘๐Ÿฟ๐Ÿ‘Ž๐Ÿ‘Ž๐Ÿป๐Ÿ‘Ž๐Ÿผ๐Ÿ‘Ž๐Ÿฝ๐Ÿ‘Ž๐Ÿพ๐Ÿ‘Ž๐ŸฟโœŠโœŠ๐ŸปโœŠ๐ŸผโœŠ๐ŸฝโœŠ๐ŸพโœŠ๐Ÿฟ๐Ÿ‘Š๐Ÿ‘Š๐Ÿป๐Ÿ‘Š๐Ÿผ๐Ÿ‘Š๐Ÿฝ๐Ÿ‘Š๐Ÿพ๐Ÿ‘Š๐Ÿฟ๐Ÿค›๐Ÿค›๐Ÿป๐Ÿค›๐Ÿผ๐Ÿค›๐Ÿฝ๐Ÿค›๐Ÿพ๐Ÿค›๐Ÿฟ๐Ÿคœ๐Ÿคœ๐Ÿป๐Ÿคœ๐Ÿผ๐Ÿคœ๐Ÿฝ๐Ÿคœ๐Ÿพ๐Ÿคœ๐Ÿฟ๐Ÿคš๐Ÿคš๐Ÿป๐Ÿคš๐Ÿผ๐Ÿคš๐Ÿฝ๐Ÿคš๐Ÿพ๐Ÿคš๐Ÿฟ๐Ÿ‘‹๐Ÿ‘‹๐Ÿป๐Ÿ‘‹๐Ÿผ๐Ÿ‘‹๐Ÿฝ๐Ÿ‘‹๐Ÿพ๐Ÿ‘‹๐Ÿฟ๐ŸคŸ๐ŸคŸ๐Ÿป๐ŸคŸ๐Ÿผ๐ŸคŸ๐Ÿฝ๐ŸคŸ๐Ÿพ๐ŸคŸ๐Ÿฟโœ๏ธโœโœ๐Ÿปโœ๐Ÿผโœ๐Ÿฝโœ๐Ÿพโœ๐Ÿฟ๐Ÿ‘๐Ÿ‘๐Ÿป๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿฝ๐Ÿ‘๐Ÿพ๐Ÿ‘๐Ÿฟ๐Ÿ‘๐Ÿ‘๐Ÿป๐Ÿ‘๐Ÿผ๐Ÿ‘๐Ÿฝ๐Ÿ‘๐Ÿพ๐Ÿ‘๐Ÿฟ๐Ÿ™Œ๐Ÿ™Œ๐Ÿป๐Ÿ™Œ๐Ÿผ๐Ÿ™Œ๐Ÿฝ๐Ÿ™Œ๐Ÿพ๐Ÿ™Œ๐Ÿฟ๐Ÿคฒ๐Ÿคฒ๐Ÿป๐Ÿคฒ๐Ÿผ๐Ÿคฒ๐Ÿฝ๐Ÿคฒ๐Ÿพ๐Ÿคฒ๐Ÿฟ๐Ÿ™๐Ÿ™๐Ÿป๐Ÿ™๐Ÿผ๐Ÿ™๐Ÿฝ๐Ÿ™๐Ÿพ๐Ÿ™๐Ÿฟ๐Ÿค๐Ÿ’…๐Ÿ’…๐Ÿป๐Ÿ’…๐Ÿผ๐Ÿ’…๐Ÿฝ๐Ÿ’…๐Ÿพ๐Ÿ’…๐Ÿฟ๐Ÿ‘‚๐Ÿ‘‚๐Ÿป๐Ÿ‘‚๐Ÿผ๐Ÿ‘‚๐Ÿฝ๐Ÿ‘‚๐Ÿพ๐Ÿ‘‚๐Ÿฟ๐Ÿ‘ƒ๐Ÿ‘ƒ๐Ÿป๐Ÿ‘ƒ๐Ÿผ๐Ÿ‘ƒ๐Ÿฝ๐Ÿ‘ƒ๐Ÿพ๐Ÿ‘ƒ๐Ÿฟ๐Ÿฆฐ๐Ÿฆฑ๐Ÿฆฒ๐Ÿฆณ๐Ÿ‘ฃ๐Ÿ‘€๐Ÿ‘๏ธ๐Ÿ‘๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ๐Ÿ‘โ€๐Ÿ—จ๏ธ๐Ÿ‘๏ธโ€๐Ÿ—จ๐Ÿ‘โ€๐Ÿ—จ๐Ÿง ๐Ÿฆด๐Ÿฆท๐Ÿ‘…๐Ÿ‘„๐Ÿ’‹๐Ÿ’˜โค๏ธโค๐Ÿ’“๐Ÿ’”๐Ÿ’•๐Ÿ’–๐Ÿ’—๐Ÿ’™๐Ÿ’š๐Ÿ’›๐Ÿงก๐Ÿ’œ๐Ÿ–ค๐Ÿ’๐Ÿ’ž๐Ÿ’Ÿโฃ๏ธโฃ๐Ÿ’Œ๐Ÿ’ค๐Ÿ’ข๐Ÿ’ฃ๐Ÿ’ฅ๐Ÿ’ฆ๐Ÿ’จ๐Ÿ’ซ๐Ÿ’ฌ๐Ÿ—จ๏ธ๐Ÿ—จ๐Ÿ—ฏ๏ธ๐Ÿ—ฏ๐Ÿ’ญ๐Ÿ•ณ๏ธ๐Ÿ•ณ๐Ÿ‘“๐Ÿ•ถ๏ธ๐Ÿ•ถ๐Ÿฅฝ๐Ÿฅผ๐Ÿ‘”๐Ÿ‘•๐Ÿ‘–๐Ÿงฃ๐Ÿงค๐Ÿงฅ๐Ÿงฆ๐Ÿ‘—๐Ÿ‘˜๐Ÿ‘™๐Ÿ‘š๐Ÿ‘›๐Ÿ‘œ๐Ÿ‘๐Ÿ›๏ธ๐Ÿ›๐ŸŽ’๐Ÿ‘ž๐Ÿ‘Ÿ๐Ÿฅพ๐Ÿฅฟ๐Ÿ‘ ๐Ÿ‘ก๐Ÿ‘ข๐Ÿ‘‘๐Ÿ‘’๐ŸŽฉ๐ŸŽ“๐Ÿงขโ›‘๏ธโ›‘๐Ÿ“ฟ๐Ÿ’„๐Ÿ’๐Ÿ’Ž๐Ÿต๐Ÿ’๐Ÿฆ๐Ÿถ๐Ÿ•๐Ÿฉ๐Ÿบ๐ŸฆŠ๐Ÿฆ๐Ÿฑ๐Ÿˆ๐Ÿฆ๐Ÿฏ๐Ÿ…๐Ÿ†๐Ÿด๐ŸŽ๐Ÿฆ„๐Ÿฆ“๐ŸฆŒ๐Ÿฎ๐Ÿ‚๐Ÿƒ๐Ÿ„๐Ÿท๐Ÿ–๐Ÿ—๐Ÿฝ๐Ÿ๐Ÿ‘๐Ÿ๐Ÿช๐Ÿซ๐Ÿฆ™๐Ÿฆ’๐Ÿ˜๐Ÿฆ๐Ÿฆ›๐Ÿญ๐Ÿ๐Ÿ€๐Ÿน๐Ÿฐ๐Ÿ‡๐Ÿฟ๏ธ๐Ÿฟ๐Ÿฆ”๐Ÿฆ‡๐Ÿป๐Ÿจ๐Ÿผ๐Ÿฆ˜๐Ÿฆก๐Ÿพ๐Ÿฆƒ๐Ÿ”๐Ÿ“๐Ÿฃ๐Ÿค๐Ÿฅ๐Ÿฆ๐Ÿง๐Ÿ•Š๏ธ๐Ÿ•Š๐Ÿฆ…๐Ÿฆ†๐Ÿฆข๐Ÿฆ‰๐Ÿฆš๐Ÿฆœ๐Ÿธ๐ŸŠ๐Ÿข๐ŸฆŽ๐Ÿ๐Ÿฒ๐Ÿ‰๐Ÿฆ•๐Ÿฆ–๐Ÿณ๐Ÿ‹๐Ÿฌ๐ŸŸ๐Ÿ ๐Ÿก๐Ÿฆˆ๐Ÿ™๐Ÿš๐Ÿฆ€๐Ÿฆž๐Ÿฆ๐Ÿฆ‘๐ŸŒ๐Ÿฆ‹๐Ÿ›๐Ÿœ๐Ÿ๐Ÿž๐Ÿฆ—๐Ÿ•ท๏ธ๐Ÿ•ท๐Ÿ•ธ๏ธ๐Ÿ•ธ๐Ÿฆ‚๐ŸฆŸ๐Ÿฆ ๐Ÿ’๐ŸŒธ๐Ÿ’ฎ๐Ÿต๏ธ๐Ÿต๐ŸŒน๐Ÿฅ€๐ŸŒบ๐ŸŒป๐ŸŒผ๐ŸŒท๐ŸŒฑ๐ŸŒฒ๐ŸŒณ๐ŸŒด๐ŸŒต๐ŸŒพ๐ŸŒฟโ˜˜๏ธโ˜˜๐Ÿ€๐Ÿ๐Ÿ‚๐Ÿƒ๐Ÿ‡๐Ÿˆ๐Ÿ‰๐ŸŠ๐Ÿ‹๐ŸŒ๐Ÿ๐Ÿฅญ๐ŸŽ๐Ÿ๐Ÿ๐Ÿ‘๐Ÿ’๐Ÿ“๐Ÿฅ๐Ÿ…๐Ÿฅฅ๐Ÿฅ‘๐Ÿ†๐Ÿฅ”๐Ÿฅ•๐ŸŒฝ๐ŸŒถ๏ธ๐ŸŒถ๐Ÿฅ’๐Ÿฅฌ๐Ÿฅฆ๐Ÿ„๐Ÿฅœ๐ŸŒฐ๐Ÿž๐Ÿฅ๐Ÿฅ–๐Ÿฅจ๐Ÿฅฏ๐Ÿฅž๐Ÿง€๐Ÿ–๐Ÿ—๐Ÿฅฉ๐Ÿฅ“๐Ÿ”๐ŸŸ๐Ÿ•๐ŸŒญ๐Ÿฅช๐ŸŒฎ๐ŸŒฏ๐Ÿฅ™๐Ÿฅš๐Ÿณ๐Ÿฅ˜๐Ÿฒ๐Ÿฅฃ๐Ÿฅ—๐Ÿฟ๐Ÿง‚๐Ÿฅซ๐Ÿฑ๐Ÿ˜๐Ÿ™๐Ÿš๐Ÿ›๐Ÿœ๐Ÿ๐Ÿ ๐Ÿข๐Ÿฃ๐Ÿค๐Ÿฅ๐Ÿฅฎ๐Ÿก๐ŸฅŸ๐Ÿฅ ๐Ÿฅก๐Ÿฆ๐Ÿง๐Ÿจ๐Ÿฉ๐Ÿช๐ŸŽ‚๐Ÿฐ๐Ÿง๐Ÿฅง๐Ÿซ๐Ÿฌ๐Ÿญ๐Ÿฎ๐Ÿฏ๐Ÿผ๐Ÿฅ›โ˜•๐Ÿต๐Ÿถ๐Ÿพ๐Ÿท๐Ÿธ๐Ÿน๐Ÿบ๐Ÿป๐Ÿฅ‚๐Ÿฅƒ๐Ÿฅค๐Ÿฅข๐Ÿฝ๏ธ๐Ÿฝ๐Ÿด๐Ÿฅ„๐Ÿ”ช๐Ÿบ๐ŸŒ๐ŸŒŽ๐ŸŒ๐ŸŒ๐Ÿ—บ๏ธ๐Ÿ—บ๐Ÿ—พ๐Ÿงญ๐Ÿ”๏ธ๐Ÿ”โ›ฐ๏ธโ›ฐ๐ŸŒ‹๐Ÿ—ป๐Ÿ•๏ธ๐Ÿ•๐Ÿ–๏ธ๐Ÿ–๐Ÿœ๏ธ๐Ÿœ๐Ÿ๏ธ๐Ÿ๐Ÿž๏ธ๐Ÿž๐ŸŸ๏ธ๐ŸŸ๐Ÿ›๏ธ๐Ÿ›๐Ÿ—๏ธ๐Ÿ—๐Ÿงฑ๐Ÿ˜๏ธ๐Ÿ˜๐Ÿš๏ธ๐Ÿš๐Ÿ ๐Ÿก๐Ÿข๐Ÿฃ๐Ÿค๐Ÿฅ๐Ÿฆ๐Ÿจ๐Ÿฉ๐Ÿช๐Ÿซ๐Ÿฌ๐Ÿญ๐Ÿฏ๐Ÿฐ๐Ÿ’’๐Ÿ—ผ๐Ÿ—ฝโ›ช๐Ÿ•Œ๐Ÿ•โ›ฉ๏ธโ›ฉ๐Ÿ•‹โ›ฒโ›บ๐ŸŒ๐ŸŒƒ๐Ÿ™๏ธ๐Ÿ™๐ŸŒ„๐ŸŒ…๐ŸŒ†๐ŸŒ‡๐ŸŒ‰โ™จ๏ธโ™จ๐ŸŒŒ๐ŸŽ ๐ŸŽก๐ŸŽข๐Ÿ’ˆ๐ŸŽช๐Ÿš‚๐Ÿšƒ๐Ÿš„๐Ÿš…๐Ÿš†๐Ÿš‡๐Ÿšˆ๐Ÿš‰๐ŸšŠ๐Ÿš๐Ÿšž๐Ÿš‹๐ŸšŒ๐Ÿš๐ŸšŽ๐Ÿš๐Ÿš‘๐Ÿš’๐Ÿš“๐Ÿš”๐Ÿš•๐Ÿš–๐Ÿš—๐Ÿš˜๐Ÿš™๐Ÿšš๐Ÿš›๐Ÿšœ๐Ÿšฒ๐Ÿ›ด๐Ÿ›น๐Ÿ›ต๐Ÿš๐Ÿ›ฃ๏ธ๐Ÿ›ฃ๐Ÿ›ค๏ธ๐Ÿ›ค๐Ÿ›ข๏ธ๐Ÿ›ขโ›ฝ๐Ÿšจ๐Ÿšฅ๐Ÿšฆ๐Ÿ›‘๐Ÿšงโš“โ›ต๐Ÿ›ถ๐Ÿšค๐Ÿ›ณ๏ธ๐Ÿ›ณโ›ด๏ธโ›ด๐Ÿ›ฅ๏ธ๐Ÿ›ฅ๐Ÿšขโœˆ๏ธโœˆ๐Ÿ›ฉ๏ธ๐Ÿ›ฉ๐Ÿ›ซ๐Ÿ›ฌ๐Ÿ’บ๐Ÿš๐ŸšŸ๐Ÿš ๐Ÿšก๐Ÿ›ฐ๏ธ๐Ÿ›ฐ๐Ÿš€๐Ÿ›ธ๐Ÿ›Ž๏ธ๐Ÿ›Ž๐ŸงณโŒ›โณโŒšโฐโฑ๏ธโฑโฒ๏ธโฒ๐Ÿ•ฐ๏ธ๐Ÿ•ฐ๐Ÿ•›๐Ÿ•ง๐Ÿ•๐Ÿ•œ๐Ÿ•‘๐Ÿ•๐Ÿ•’๐Ÿ•ž๐Ÿ•“๐Ÿ•Ÿ๐Ÿ•”๐Ÿ• ๐Ÿ••๐Ÿ•ก๐Ÿ•–๐Ÿ•ข๐Ÿ•—๐Ÿ•ฃ๐Ÿ•˜๐Ÿ•ค๐Ÿ•™๐Ÿ•ฅ๐Ÿ•š๐Ÿ•ฆ๐ŸŒ‘๐ŸŒ’๐ŸŒ“๐ŸŒ”๐ŸŒ•๐ŸŒ–๐ŸŒ—๐ŸŒ˜๐ŸŒ™๐ŸŒš๐ŸŒ›๐ŸŒœ๐ŸŒก๏ธ๐ŸŒกโ˜€๏ธโ˜€๐ŸŒ๐ŸŒžโญ๐ŸŒŸ๐ŸŒ โ˜๏ธโ˜โ›…โ›ˆ๏ธโ›ˆ๐ŸŒค๏ธ๐ŸŒค๐ŸŒฅ๏ธ๐ŸŒฅ๐ŸŒฆ๏ธ๐ŸŒฆ๐ŸŒง๏ธ๐ŸŒง๐ŸŒจ๏ธ๐ŸŒจ๐ŸŒฉ๏ธ๐ŸŒฉ๐ŸŒช๏ธ๐ŸŒช๐ŸŒซ๏ธ๐ŸŒซ๐ŸŒฌ๏ธ๐ŸŒฌ๐ŸŒ€๐ŸŒˆ๐ŸŒ‚โ˜‚๏ธโ˜‚โ˜”โ›ฑ๏ธโ›ฑโšกโ„๏ธโ„โ˜ƒ๏ธโ˜ƒโ›„โ˜„๏ธโ˜„๐Ÿ”ฅ๐Ÿ’ง๐ŸŒŠ๐ŸŽƒ๐ŸŽ„๐ŸŽ†๐ŸŽ‡๐Ÿงจโœจ๐ŸŽˆ๐ŸŽ‰๐ŸŽŠ๐ŸŽ‹๐ŸŽ๐ŸŽŽ๐ŸŽ๐ŸŽ๐ŸŽ‘๐Ÿงง๐ŸŽ€๐ŸŽ๐ŸŽ—๏ธ๐ŸŽ—๐ŸŽŸ๏ธ๐ŸŽŸ๐ŸŽซ๐ŸŽ–๏ธ๐ŸŽ–๐Ÿ†๐Ÿ…๐Ÿฅ‡๐Ÿฅˆ๐Ÿฅ‰โšฝโšพ๐ŸฅŽ๐Ÿ€๐Ÿ๐Ÿˆ๐Ÿ‰๐ŸŽพ๐Ÿฅ๐ŸŽณ๐Ÿ๐Ÿ‘๐Ÿ’๐Ÿฅ๐Ÿ“๐Ÿธ๐ŸฅŠ๐Ÿฅ‹๐Ÿฅ…โ›ณโ›ธ๏ธโ›ธ๐ŸŽฃ๐ŸŽฝ๐ŸŽฟ๐Ÿ›ท๐ŸฅŒ๐ŸŽฏ๐ŸŽฑ๐Ÿ”ฎ๐Ÿงฟ๐ŸŽฎ๐Ÿ•น๏ธ๐Ÿ•น๐ŸŽฐ๐ŸŽฒ๐Ÿงฉ๐Ÿงธโ™ ๏ธโ™ โ™ฅ๏ธโ™ฅโ™ฆ๏ธโ™ฆโ™ฃ๏ธโ™ฃโ™Ÿ๏ธโ™Ÿ๐Ÿƒ๐Ÿ€„๐ŸŽด๐ŸŽญ๐Ÿ–ผ๏ธ๐Ÿ–ผ๐ŸŽจ๐Ÿงต๐Ÿงถ๐Ÿ”‡๐Ÿ”ˆ๐Ÿ”‰๐Ÿ”Š๐Ÿ“ข๐Ÿ“ฃ๐Ÿ“ฏ๐Ÿ””๐Ÿ”•๐ŸŽผ๐ŸŽต๐ŸŽถ๐ŸŽ™๏ธ๐ŸŽ™๐ŸŽš๏ธ๐ŸŽš๐ŸŽ›๏ธ๐ŸŽ›๐ŸŽค๐ŸŽง๐Ÿ“ป๐ŸŽท๐ŸŽธ๐ŸŽน๐ŸŽบ๐ŸŽป๐Ÿฅ๐Ÿ“ฑ๐Ÿ“ฒโ˜Ž๏ธโ˜Ž๐Ÿ“ž๐Ÿ“Ÿ๐Ÿ“ ๐Ÿ”‹๐Ÿ”Œ๐Ÿ’ป๐Ÿ–ฅ๏ธ๐Ÿ–ฅ๐Ÿ–จ๏ธ๐Ÿ–จโŒจ๏ธโŒจ๐Ÿ–ฑ๏ธ๐Ÿ–ฑ๐Ÿ–ฒ๏ธ๐Ÿ–ฒ๐Ÿ’ฝ๐Ÿ’พ๐Ÿ’ฟ๐Ÿ“€๐Ÿงฎ๐ŸŽฅ๐ŸŽž๏ธ๐ŸŽž๐Ÿ“ฝ๏ธ๐Ÿ“ฝ๐ŸŽฌ๐Ÿ“บ๐Ÿ“ท๐Ÿ“ธ๐Ÿ“น๐Ÿ“ผ๐Ÿ”๐Ÿ”Ž๐Ÿ•ฏ๏ธ๐Ÿ•ฏ๐Ÿ’ก๐Ÿ”ฆ๐Ÿฎ๐Ÿ“”๐Ÿ“•๐Ÿ“–๐Ÿ“—๐Ÿ“˜๐Ÿ“™๐Ÿ“š๐Ÿ““๐Ÿ“’๐Ÿ“ƒ๐Ÿ“œ๐Ÿ“„๐Ÿ“ฐ๐Ÿ—ž๏ธ๐Ÿ—ž๐Ÿ“‘๐Ÿ”–๐Ÿท๏ธ๐Ÿท๐Ÿ’ฐ๐Ÿ’ด๐Ÿ’ต๐Ÿ’ถ๐Ÿ’ท๐Ÿ’ธ๐Ÿ’ณ๐Ÿงพ๐Ÿ’น๐Ÿ’ฑ๐Ÿ’ฒโœ‰๏ธโœ‰๐Ÿ“ง๐Ÿ“จ๐Ÿ“ฉ๐Ÿ“ค๐Ÿ“ฅ๐Ÿ“ฆ๐Ÿ“ซ๐Ÿ“ช๐Ÿ“ฌ๐Ÿ“ญ๐Ÿ“ฎ๐Ÿ—ณ๏ธ๐Ÿ—ณโœ๏ธโœโœ’๏ธโœ’๐Ÿ–‹๏ธ๐Ÿ–‹๐Ÿ–Š๏ธ๐Ÿ–Š๐Ÿ–Œ๏ธ๐Ÿ–Œ๐Ÿ–๏ธ๐Ÿ–๐Ÿ“๐Ÿ’ผ๐Ÿ“๐Ÿ“‚๐Ÿ—‚๏ธ๐Ÿ—‚๐Ÿ“…๐Ÿ“†๐Ÿ—’๏ธ๐Ÿ—’๐Ÿ—“๏ธ๐Ÿ—“๐Ÿ“‡๐Ÿ“ˆ๐Ÿ“‰๐Ÿ“Š๐Ÿ“‹๐Ÿ“Œ๐Ÿ“๐Ÿ“Ž๐Ÿ–‡๏ธ๐Ÿ–‡๐Ÿ“๐Ÿ“โœ‚๏ธโœ‚๐Ÿ—ƒ๏ธ๐Ÿ—ƒ๐Ÿ—„๏ธ๐Ÿ—„๐Ÿ—‘๏ธ๐Ÿ—‘๐Ÿ”’๐Ÿ”“๐Ÿ”๐Ÿ”๐Ÿ”‘๐Ÿ—๏ธ๐Ÿ—๐Ÿ”จโ›๏ธโ›โš’๏ธโš’๐Ÿ› ๏ธ๐Ÿ› ๐Ÿ—ก๏ธ๐Ÿ—กโš”๏ธโš”๐Ÿ”ซ๐Ÿน๐Ÿ›ก๏ธ๐Ÿ›ก๐Ÿ”ง๐Ÿ”ฉโš™๏ธโš™๐Ÿ—œ๏ธ๐Ÿ—œโš–๏ธโš–๐Ÿ”—โ›“๏ธโ›“๐Ÿงฐ๐Ÿงฒโš—๏ธโš—๐Ÿงช๐Ÿงซ๐Ÿงฌ๐Ÿ”ฌ๐Ÿ”ญ๐Ÿ“ก๐Ÿ’‰๐Ÿ’Š๐Ÿšช๐Ÿ›๏ธ๐Ÿ›๐Ÿ›‹๏ธ๐Ÿ›‹๐Ÿšฝ๐Ÿšฟ๐Ÿ›๐Ÿงด๐Ÿงท๐Ÿงน๐Ÿงบ๐Ÿงป๐Ÿงผ๐Ÿงฝ๐Ÿงฏ๐Ÿ›’๐Ÿšฌโšฐ๏ธโšฐโšฑ๏ธโšฑ๐Ÿ—ฟ๐Ÿง๐Ÿšฎ๐Ÿšฐโ™ฟ๐Ÿšน๐Ÿšบ๐Ÿšป๐Ÿšผ๐Ÿšพ๐Ÿ›‚๐Ÿ›ƒ๐Ÿ›„๐Ÿ›…โš ๏ธโš ๐Ÿšธโ›”๐Ÿšซ๐Ÿšณ๐Ÿšญ๐Ÿšฏ๐Ÿšฑ๐Ÿšท๐Ÿ“ต๐Ÿ”žโ˜ข๏ธโ˜ขโ˜ฃ๏ธโ˜ฃโฌ†๏ธโฌ†โ†—๏ธโ†—โžก๏ธโžกโ†˜๏ธโ†˜โฌ‡๏ธโฌ‡โ†™๏ธโ†™โฌ…๏ธโฌ…โ†–๏ธโ†–โ†•๏ธโ†•โ†”๏ธโ†”โ†ฉ๏ธโ†ฉโ†ช๏ธโ†ชโคด๏ธโคดโคต๏ธโคต๐Ÿ”ƒ๐Ÿ”„๐Ÿ”™๐Ÿ”š๐Ÿ”›๐Ÿ”œ๐Ÿ”๐Ÿ›โš›๏ธโš›๐Ÿ•‰๏ธ๐Ÿ•‰โœก๏ธโœกโ˜ธ๏ธโ˜ธโ˜ฏ๏ธโ˜ฏโœ๏ธโœโ˜ฆ๏ธโ˜ฆโ˜ช๏ธโ˜ชโ˜ฎ๏ธโ˜ฎ๐Ÿ•Ž๐Ÿ”ฏโ™ˆโ™‰โ™Šโ™‹โ™Œโ™โ™Žโ™โ™โ™‘โ™’โ™“โ›Ž๐Ÿ”€๐Ÿ”๐Ÿ”‚โ–ถ๏ธโ–ถโฉโญ๏ธโญโฏ๏ธโฏโ—€๏ธโ—€โชโฎ๏ธโฎ๐Ÿ”ผโซ๐Ÿ”ฝโฌโธ๏ธโธโน๏ธโนโบ๏ธโบโ๏ธโ๐ŸŽฆ๐Ÿ”…๐Ÿ”†๐Ÿ“ถ๐Ÿ“ณ๐Ÿ“ดโ™€๏ธโ™€โ™‚๏ธโ™‚โš•๏ธโš•โ™พ๏ธโ™พโ™ป๏ธโ™ปโšœ๏ธโšœ๐Ÿ”ฑ๐Ÿ“›๐Ÿ”ฐโญ•โœ…โ˜‘๏ธโ˜‘โœ”๏ธโœ”โœ–๏ธโœ–โŒโŽโž•โž–โž—โžฐโžฟใ€ฝ๏ธใ€ฝโœณ๏ธโœณโœด๏ธโœดโ‡๏ธโ‡โ€ผ๏ธโ€ผโ‰๏ธโ‰โ“โ”โ•โ—ใ€ฐ๏ธใ€ฐยฉ๏ธยฉยฎ๏ธยฎโ„ข๏ธโ„ข#๏ธโƒฃ#โƒฃ*๏ธโƒฃ*โƒฃ0๏ธโƒฃ0โƒฃ1๏ธโƒฃ1โƒฃ2๏ธโƒฃ2โƒฃ3๏ธโƒฃ3โƒฃ4๏ธโƒฃ4โƒฃ5๏ธโƒฃ5โƒฃ6๏ธโƒฃ6โƒฃ7๏ธโƒฃ7โƒฃ8๏ธโƒฃ8โƒฃ9๏ธโƒฃ9โƒฃ๐Ÿ”Ÿ๐Ÿ’ฏ๐Ÿ” ๐Ÿ”ก๐Ÿ”ข๐Ÿ”ฃ๐Ÿ”ค๐Ÿ…ฐ๏ธ๐Ÿ…ฐ๐Ÿ†Ž๐Ÿ…ฑ๏ธ๐Ÿ…ฑ๐Ÿ†‘๐Ÿ†’๐Ÿ†“โ„น๏ธโ„น๐Ÿ†”โ“‚๏ธโ“‚๐Ÿ†•๐Ÿ†–๐Ÿ…พ๏ธ๐Ÿ…พ๐Ÿ†—๐Ÿ…ฟ๏ธ๐Ÿ…ฟ๐Ÿ†˜๐Ÿ†™๐Ÿ†š๐Ÿˆ๐Ÿˆ‚๏ธ๐Ÿˆ‚๐Ÿˆท๏ธ๐Ÿˆท๐Ÿˆถ๐Ÿˆฏ๐Ÿ‰๐Ÿˆน๐Ÿˆš๐Ÿˆฒ๐Ÿ‰‘๐Ÿˆธ๐Ÿˆด๐ŸˆณใŠ—๏ธใŠ—ใŠ™๏ธใŠ™๐Ÿˆบ๐Ÿˆตโ–ช๏ธโ–ชโ–ซ๏ธโ–ซโ—ป๏ธโ—ปโ—ผ๏ธโ—ผโ—ฝโ—พโฌ›โฌœ๐Ÿ”ถ๐Ÿ”ท๐Ÿ”ธ๐Ÿ”น๐Ÿ”บ๐Ÿ”ป๐Ÿ’ ๐Ÿ”˜๐Ÿ”ฒ๐Ÿ”ณโšชโšซ๐Ÿ”ด๐Ÿ”ต๐Ÿ๐Ÿšฉ๐ŸŽŒ๐Ÿด๐Ÿณ๏ธ๐Ÿณ๐Ÿณ๏ธโ€๐ŸŒˆ๐Ÿณโ€๐ŸŒˆ๐Ÿดโ€โ˜ ๏ธ๐Ÿดโ€โ˜ ๐Ÿ‡ฆ๐Ÿ‡จ๐Ÿ‡ฆ๐Ÿ‡ฉ๐Ÿ‡ฆ๐Ÿ‡ช๐Ÿ‡ฆ๐Ÿ‡ซ๐Ÿ‡ฆ๐Ÿ‡ฌ๐Ÿ‡ฆ๐Ÿ‡ฎ๐Ÿ‡ฆ๐Ÿ‡ฑ๐Ÿ‡ฆ๐Ÿ‡ฒ๐Ÿ‡ฆ๐Ÿ‡ด๐Ÿ‡ฆ๐Ÿ‡ถ๐Ÿ‡ฆ๐Ÿ‡ท๐Ÿ‡ฆ๐Ÿ‡ธ๐Ÿ‡ฆ๐Ÿ‡น๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ‡ฆ๐Ÿ‡ผ๐Ÿ‡ฆ๐Ÿ‡ฝ๐Ÿ‡ฆ๐Ÿ‡ฟ๐Ÿ‡ง๐Ÿ‡ฆ๐Ÿ‡ง๐Ÿ‡ง๐Ÿ‡ง๐Ÿ‡ฉ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ง๐Ÿ‡ซ๐Ÿ‡ง๐Ÿ‡ฌ๐Ÿ‡ง๐Ÿ‡ญ๐Ÿ‡ง๐Ÿ‡ฎ๐Ÿ‡ง๐Ÿ‡ฏ๐Ÿ‡ง๐Ÿ‡ฑ๐Ÿ‡ง๐Ÿ‡ฒ๐Ÿ‡ง๐Ÿ‡ณ๐Ÿ‡ง๐Ÿ‡ด๐Ÿ‡ง๐Ÿ‡ถ๐Ÿ‡ง๐Ÿ‡ท๐Ÿ‡ง๐Ÿ‡ธ๐Ÿ‡ง๐Ÿ‡น๐Ÿ‡ง๐Ÿ‡ป๐Ÿ‡ง๐Ÿ‡ผ๐Ÿ‡ง๐Ÿ‡พ๐Ÿ‡ง๐Ÿ‡ฟ๐Ÿ‡จ๐Ÿ‡ฆ๐Ÿ‡จ๐Ÿ‡จ๐Ÿ‡จ๐Ÿ‡ฉ๐Ÿ‡จ๐Ÿ‡ซ๐Ÿ‡จ๐Ÿ‡ฌ๐Ÿ‡จ๐Ÿ‡ญ๐Ÿ‡จ๐Ÿ‡ฎ๐Ÿ‡จ๐Ÿ‡ฐ๐Ÿ‡จ๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฒ๐Ÿ‡จ๐Ÿ‡ณ๐Ÿ‡จ๐Ÿ‡ด๐Ÿ‡จ๐Ÿ‡ต๐Ÿ‡จ๐Ÿ‡ท๐Ÿ‡จ๐Ÿ‡บ๐Ÿ‡จ๐Ÿ‡ป๐Ÿ‡จ๐Ÿ‡ผ๐Ÿ‡จ๐Ÿ‡ฝ๐Ÿ‡จ๐Ÿ‡พ๐Ÿ‡จ๐Ÿ‡ฟ๐Ÿ‡ฉ๐Ÿ‡ช๐Ÿ‡ฉ๐Ÿ‡ฌ๐Ÿ‡ฉ๐Ÿ‡ฏ๐Ÿ‡ฉ๐Ÿ‡ฐ๐Ÿ‡ฉ๐Ÿ‡ฒ๐Ÿ‡ฉ๐Ÿ‡ด๐Ÿ‡ฉ๐Ÿ‡ฟ๐Ÿ‡ช๐Ÿ‡ฆ๐Ÿ‡ช๐Ÿ‡จ๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡ฌ๐Ÿ‡ช๐Ÿ‡ญ๐Ÿ‡ช๐Ÿ‡ท๐Ÿ‡ช๐Ÿ‡ธ๐Ÿ‡ช๐Ÿ‡น๐Ÿ‡ช๐Ÿ‡บ๐Ÿ‡ซ๐Ÿ‡ฎ๐Ÿ‡ซ๐Ÿ‡ฏ๐Ÿ‡ซ๐Ÿ‡ฐ๐Ÿ‡ซ๐Ÿ‡ฒ๐Ÿ‡ซ๐Ÿ‡ด๐Ÿ‡ซ๐Ÿ‡ท๐Ÿ‡ฌ๐Ÿ‡ฆ๐Ÿ‡ฌ๐Ÿ‡ง๐Ÿ‡ฌ๐Ÿ‡ฉ๐Ÿ‡ฌ๐Ÿ‡ช๐Ÿ‡ฌ๐Ÿ‡ซ๐Ÿ‡ฌ๐Ÿ‡ฌ๐Ÿ‡ฌ๐Ÿ‡ญ๐Ÿ‡ฌ๐Ÿ‡ฎ๐Ÿ‡ฌ๐Ÿ‡ฑ๐Ÿ‡ฌ๐Ÿ‡ฒ๐Ÿ‡ฌ๐Ÿ‡ณ๐Ÿ‡ฌ๐Ÿ‡ต๐Ÿ‡ฌ๐Ÿ‡ถ๐Ÿ‡ฌ๐Ÿ‡ท๐Ÿ‡ฌ๐Ÿ‡ธ๐Ÿ‡ฌ๐Ÿ‡น๐Ÿ‡ฌ๐Ÿ‡บ๐Ÿ‡ฌ๐Ÿ‡ผ๐Ÿ‡ฌ๐Ÿ‡พ๐Ÿ‡ญ๐Ÿ‡ฐ๐Ÿ‡ญ๐Ÿ‡ฒ๐Ÿ‡ญ๐Ÿ‡ณ๐Ÿ‡ญ๐Ÿ‡ท๐Ÿ‡ญ๐Ÿ‡น๐Ÿ‡ญ๐Ÿ‡บ๐Ÿ‡ฎ๐Ÿ‡จ๐Ÿ‡ฎ๐Ÿ‡ฉ๐Ÿ‡ฎ๐Ÿ‡ช๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡ฎ๐Ÿ‡ฒ๐Ÿ‡ฎ๐Ÿ‡ณ๐Ÿ‡ฎ๐Ÿ‡ด๐Ÿ‡ฎ๐Ÿ‡ถ๐Ÿ‡ฎ๐Ÿ‡ท๐Ÿ‡ฎ๐Ÿ‡ธ๐Ÿ‡ฎ๐Ÿ‡น๐Ÿ‡ฏ๐Ÿ‡ช๐Ÿ‡ฏ๐Ÿ‡ฒ๐Ÿ‡ฏ๐Ÿ‡ด๐Ÿ‡ฏ๐Ÿ‡ต๐Ÿ‡ฐ๐Ÿ‡ช๐Ÿ‡ฐ๐Ÿ‡ฌ๐Ÿ‡ฐ๐Ÿ‡ญ๐Ÿ‡ฐ๐Ÿ‡ฎ๐Ÿ‡ฐ๐Ÿ‡ฒ๐Ÿ‡ฐ๐Ÿ‡ณ๐Ÿ‡ฐ๐Ÿ‡ต๐Ÿ‡ฐ๐Ÿ‡ท๐Ÿ‡ฐ๐Ÿ‡ผ๐Ÿ‡ฐ๐Ÿ‡พ๐Ÿ‡ฐ๐Ÿ‡ฟ๐Ÿ‡ฑ๐Ÿ‡ฆ๐Ÿ‡ฑ๐Ÿ‡ง๐Ÿ‡ฑ๐Ÿ‡จ๐Ÿ‡ฑ๐Ÿ‡ฎ๐Ÿ‡ฑ๐Ÿ‡ฐ๐Ÿ‡ฑ๐Ÿ‡ท๐Ÿ‡ฑ๐Ÿ‡ธ๐Ÿ‡ฑ๐Ÿ‡น๐Ÿ‡ฑ๐Ÿ‡บ๐Ÿ‡ฑ๐Ÿ‡ป๐Ÿ‡ฑ๐Ÿ‡พ๐Ÿ‡ฒ๐Ÿ‡ฆ๐Ÿ‡ฒ๐Ÿ‡จ๐Ÿ‡ฒ๐Ÿ‡ฉ๐Ÿ‡ฒ๐Ÿ‡ช๐Ÿ‡ฒ๐Ÿ‡ซ๐Ÿ‡ฒ๐Ÿ‡ฌ๐Ÿ‡ฒ๐Ÿ‡ญ๐Ÿ‡ฒ๐Ÿ‡ฐ๐Ÿ‡ฒ๐Ÿ‡ฑ๐Ÿ‡ฒ๐Ÿ‡ฒ๐Ÿ‡ฒ๐Ÿ‡ณ๐Ÿ‡ฒ๐Ÿ‡ด๐Ÿ‡ฒ๐Ÿ‡ต๐Ÿ‡ฒ๐Ÿ‡ถ๐Ÿ‡ฒ๐Ÿ‡ท๐Ÿ‡ฒ๐Ÿ‡ธ๐Ÿ‡ฒ๐Ÿ‡น๐Ÿ‡ฒ๐Ÿ‡บ๐Ÿ‡ฒ๐Ÿ‡ป๐Ÿ‡ฒ๐Ÿ‡ผ๐Ÿ‡ฒ๐Ÿ‡ฝ๐Ÿ‡ฒ๐Ÿ‡พ๐Ÿ‡ฒ๐Ÿ‡ฟ๐Ÿ‡ณ๐Ÿ‡ฆ๐Ÿ‡ณ๐Ÿ‡จ๐Ÿ‡ณ๐Ÿ‡ช๐Ÿ‡ณ๐Ÿ‡ซ๐Ÿ‡ณ๐Ÿ‡ฌ๐Ÿ‡ณ๐Ÿ‡ฎ๐Ÿ‡ณ๐Ÿ‡ฑ๐Ÿ‡ณ๐Ÿ‡ด๐Ÿ‡ณ๐Ÿ‡ต๐Ÿ‡ณ๐Ÿ‡ท๐Ÿ‡ณ๐Ÿ‡บ๐Ÿ‡ณ๐Ÿ‡ฟ๐Ÿ‡ด๐Ÿ‡ฒ๐Ÿ‡ต๐Ÿ‡ฆ๐Ÿ‡ต๐Ÿ‡ช๐Ÿ‡ต๐Ÿ‡ซ๐Ÿ‡ต๐Ÿ‡ฌ๐Ÿ‡ต๐Ÿ‡ญ๐Ÿ‡ต๐Ÿ‡ฐ๐Ÿ‡ต๐Ÿ‡ฑ๐Ÿ‡ต๐Ÿ‡ฒ๐Ÿ‡ต๐Ÿ‡ณ๐Ÿ‡ต๐Ÿ‡ท๐Ÿ‡ต๐Ÿ‡ธ๐Ÿ‡ต๐Ÿ‡น๐Ÿ‡ต๐Ÿ‡ผ๐Ÿ‡ต๐Ÿ‡พ๐Ÿ‡ถ๐Ÿ‡ฆ๐Ÿ‡ท๐Ÿ‡ช๐Ÿ‡ท๐Ÿ‡ด๐Ÿ‡ท๐Ÿ‡ธ๐Ÿ‡ท๐Ÿ‡บ๐Ÿ‡ท๐Ÿ‡ผ๐Ÿ‡ธ๐Ÿ‡ฆ๐Ÿ‡ธ๐Ÿ‡ง๐Ÿ‡ธ๐Ÿ‡จ๐Ÿ‡ธ๐Ÿ‡ฉ๐Ÿ‡ธ๐Ÿ‡ช๐Ÿ‡ธ๐Ÿ‡ฌ๐Ÿ‡ธ๐Ÿ‡ญ๐Ÿ‡ธ๐Ÿ‡ฎ๐Ÿ‡ธ๐Ÿ‡ฏ๐Ÿ‡ธ๐Ÿ‡ฐ๐Ÿ‡ธ๐Ÿ‡ฑ๐Ÿ‡ธ๐Ÿ‡ฒ๐Ÿ‡ธ๐Ÿ‡ณ๐Ÿ‡ธ๐Ÿ‡ด๐Ÿ‡ธ๐Ÿ‡ท๐Ÿ‡ธ๐Ÿ‡ธ๐Ÿ‡ธ๐Ÿ‡น๐Ÿ‡ธ๐Ÿ‡ป๐Ÿ‡ธ๐Ÿ‡ฝ๐Ÿ‡ธ๐Ÿ‡พ๐Ÿ‡ธ๐Ÿ‡ฟ๐Ÿ‡น๐Ÿ‡ฆ๐Ÿ‡น๐Ÿ‡จ๐Ÿ‡น๐Ÿ‡ฉ๐Ÿ‡น๐Ÿ‡ซ๐Ÿ‡น๐Ÿ‡ฌ๐Ÿ‡น๐Ÿ‡ญ๐Ÿ‡น๐Ÿ‡ฏ๐Ÿ‡น๐Ÿ‡ฐ๐Ÿ‡น๐Ÿ‡ฑ๐Ÿ‡น๐Ÿ‡ฒ๐Ÿ‡น๐Ÿ‡ณ๐Ÿ‡น๐Ÿ‡ด๐Ÿ‡น๐Ÿ‡ท๐Ÿ‡น๐Ÿ‡น๐Ÿ‡น๐Ÿ‡ป๐Ÿ‡น๐Ÿ‡ผ๐Ÿ‡น๐Ÿ‡ฟ๐Ÿ‡บ๐Ÿ‡ฆ๐Ÿ‡บ๐Ÿ‡ฌ๐Ÿ‡บ๐Ÿ‡ฒ๐Ÿ‡บ๐Ÿ‡ณ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ‡บ๐Ÿ‡พ๐Ÿ‡บ๐Ÿ‡ฟ๐Ÿ‡ป๐Ÿ‡ฆ๐Ÿ‡ป๐Ÿ‡จ๐Ÿ‡ป๐Ÿ‡ช๐Ÿ‡ป๐Ÿ‡ฌ๐Ÿ‡ป๐Ÿ‡ฎ๐Ÿ‡ป๐Ÿ‡ณ๐Ÿ‡ป๐Ÿ‡บ๐Ÿ‡ผ๐Ÿ‡ซ๐Ÿ‡ผ๐Ÿ‡ธ๐Ÿ‡ฝ๐Ÿ‡ฐ๐Ÿ‡พ๐Ÿ‡ช๐Ÿ‡พ๐Ÿ‡น๐Ÿ‡ฟ๐Ÿ‡ฆ๐Ÿ‡ฟ๐Ÿ‡ฒ๐Ÿ‡ฟ๐Ÿ‡ผ๐Ÿด๓ ง๓ ข๓ ฅ๓ ฎ๓ ง๓ ฟ๐Ÿด๓ ง๓ ข๓ ณ๓ ฃ๓ ด๓ ฟ๐Ÿด๓ ง๓ ข๓ ท๓ ฌ๓ ณ๓ ฟ"
  );
  expect(() => emoji.parse(":-)")).toThrow();
  expect(() => emoji.parse("๐Ÿ˜€ is an emoji")).toThrow();
  expect(() => emoji.parse("๐Ÿ˜€stuff")).toThrow();
  expect(() => emoji.parse("stuff๐Ÿ˜€")).toThrow();

  emoji.parse("1\u{FE0F}\u{20E3}"); // keycap sequences stay valid
  emoji.parse("#\u{FE0F}\u{20E3}");

  // `\p{Emoji_Component}` alone covers ASCII digits, "#", "*", ZWJ, variation selectors and skin tone modifiers; none is an emoji without a base, so a component-only string is not one either
  expect(() => emoji.parse("123")).toThrow();
  expect(() => emoji.parse("#")).toThrow();
  expect(() => emoji.parse("*")).toThrow();
  expect(() => emoji.parse("\u{200D}")).toThrow();
  expect(() => emoji.parse("\u{FE0F}")).toThrow();
  expect(() => emoji.parse("\u{1F3FD}")).toThrow();
  expect(() => emoji.parse("1\u{FE0F}")).toThrow();
});

test("nanoid", () => {
  const nanoid = z.string().nanoid("custom error");
  nanoid.parse("lfNZluvAxMkf7Q8C5H-QS");
  nanoid.parse("mIU_4PJWikaU8fMbmkouz");
  nanoid.parse("Hb9ZUtUa2JDm_dD-47EGv");
  nanoid.parse("5Noocgv_8vQ9oPijj4ioQ");
  const result = nanoid.safeParse("Xq90uDyhddC53KsoASYJGX");
  expect(result).toMatchObject({ success: false });

  expect(result.error!.issues[0].message).toEqual("custom error");
  expect(result.error).toMatchInlineSnapshot(`
    [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "nanoid",
        "pattern": "/^[a-zA-Z0-9_-]{21}$/",
        "path": [],
        "message": "custom error"
      }
    ]]
  `);
});

test("bad nanoid", () => {
  const nanoid = z.string().nanoid("custom error");
  nanoid.parse("ySh_984wpDUu7IQRrLXAp");
  const result = nanoid.safeParse("invalid nanoid");
  expect(result).toMatchObject({ success: false });

  expect(result.error!.issues[0].message).toEqual("custom error");
  expect(result.error).toMatchInlineSnapshot(`
    [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "nanoid",
        "pattern": "/^[a-zA-Z0-9_-]{21}$/",
        "path": [],
        "message": "custom error"
      }
    ]]
  `);
});

test("good uuid", () => {
  const uuid = z.string().uuid("custom error");
  const goodUuids = [
    "9491d710-3185-1e06-bea0-6a2f275345e0",
    "9491d710-3185-2e06-bea0-6a2f275345e0",
    "9491d710-3185-3e06-bea0-6a2f275345e0",
    "9491d710-3185-4e06-bea0-6a2f275345e0",
    "9491d710-3185-5e06-bea0-6a2f275345e0",
    "9491d710-3185-5e06-aea0-6a2f275345e0",
    "9491d710-3185-5e06-8ea0-6a2f275345e0",
    "9491d710-3185-5e06-9ea0-6a2f275345e0",
    "00000000-0000-0000-0000-000000000000",
    "ffffffff-ffff-ffff-ffff-ffffffffffff",
  ];

  for (const goodUuid of goodUuids) {
    const result = uuid.safeParse(goodUuid);
    expect(result.success).toEqual(true);
  }
});

test(`bad uuid`, () => {
  const uuid = z.string().uuid("custom error");
  for (const badUuid of [
    "9491d710-3185-0e06-bea0-6a2f275345e0",
    "9491d710-3185-5e06-0ea0-6a2f275345e0",
    "d89e7b01-7598-ed11-9d7a-0022489382fd", // new sequential id
    "b3ce60f8-e8b9-40f5-1150-172ede56ff74", // Variant 0 - RFC 9562/4122: Reserved, NCS backward compatibility
    "92e76bf9-28b3-4730-cd7f-cb6bc51f8c09", // Variant 2 - RFC 9562/4122: Reserved, Microsoft Corporation backward compatibility
    "invalid uuid",
    "9491d710-3185-4e06-bea0-6a2f275345e0X",
  ]) {
    const result = uuid.safeParse(badUuid);
    expect(result).toMatchObject({ success: false });
    expect(result.error?.issues[0].message).toEqual("custom error");
  }
});

test("good guid", () => {
  const guid = z.string().guid("custom error");
  for (const goodGuid of [
    "9491d710-3185-4e06-bea0-6a2f275345e0",
    "d89e7b01-7598-ed11-9d7a-0022489382fd", // new sequential id
    "b3ce60f8-e8b9-40f5-1150-172ede56ff74", // Variant 0 - RFC 9562/4122: Reserved, NCS backward compatibility
    "92e76bf9-28b3-4730-cd7f-cb6bc51f8c09", // Variant 2 - RFC 9562/4122: Reserved, Microsoft Corporation backward compatibility
    "00000000-0000-0000-0000-000000000000",
    "ffffffff-ffff-ffff-ffff-ffffffffffff",
  ]) {
    const result = guid.safeParse(goodGuid);
    expect(result.success).toEqual(true);
  }
});

test("bad guid", () => {
  const guid = z.string().guid("custom error");
  for (const badGuid of ["9491d710-3185-4e06-bea0-6a2f275345e0X"]) {
    const result = guid.safeParse(badGuid);
    expect(result).toMatchObject({ success: false });
    expect(result.error?.issues[0].message).toEqual("custom error");
  }
});

test("nanoid custom length", () => {
  const nanoid64 = z.nanoid({ length: 64 });
  nanoid64.parse("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
  expect(nanoid64.safeParse("lfNZluvAxMkf7Q8C5H-QS")).toMatchObject({ success: false });

  // the deprecated method and the default length both still work
  expect(z.string().nanoid({ length: 10 }).safeParse("IRFa-VaY2b")).toMatchObject({ success: true });
  expect(z.nanoid().safeParse("lfNZluvAxMkf7Q8C5H-QS")).toMatchObject({ success: true });

  expect(z.nanoid({ length: 64, error: "custom error" }).safeParse("abc").error!.issues[0].message).toEqual(
    "custom error"
  );
});

test("nanoid rejects a length that is not a positive integer", () => {
  expect(() => z.nanoid({ length: 0 })).toThrow("Invalid nanoid length: 0");
  expect(() => z.nanoid({ length: -1 })).toThrow("Invalid nanoid length: -1");
  expect(() => z.nanoid({ length: 1.5 })).toThrow("Invalid nanoid length: 1.5");
});

test("cuid", () => {
  const cuid = z.string().cuid();
  cuid.parse("ckopqwooh000001la8mbi2im9");
  const result = cuid.safeParse("cifjhdsfhsd-invalid-cuid");
  expect(result).toMatchObject({ success: false });

  expect(result.error!.issues[0].message).toEqual("Invalid cuid");
  expect(result.error).toMatchInlineSnapshot(`
    [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "cuid",
        "pattern": "/^[cC][0-9a-z]{6,}$/",
        "path": [],
        "message": "Invalid cuid"
      }
    ]]
  `);

  // Strings containing non-base36 characters that the old denylist regex
  // (/^[cC][^\s-]{8,}$/) accepted. The new regex restricts the body to
  // [0-9a-z], matching the actual CUID v1 base36 format. See #3621.
  const previouslyAcceptedNonCuids = [
    "cly63t164000245zw008pggon';select1;", // SQLi-shaped (no whitespace, no hyphen)
    "c<script>alert(1)</script>aaaaaa", // XSS-shaped
    "c{};alert(1)//", // bracket / curly chars
    "C0123_45678", // underscore is not base36
    "cAAAAAAAAA", // uppercase letters in body are not base36 (CUIDs are lowercase)
  ];
  for (const s of previouslyAcceptedNonCuids) {
    expect(cuid.safeParse(s).success).toBe(false);
  }
});

test("cuid2", () => {
  const cuid2 = z.string().cuid2();
  const validStrings = [
    "a", // short string
    "tz4a98xxat96iws9zmbrgj3a", // normal string
    "kf5vz6ssxe4zjcb409rjgo747tc5qjazgptvotk6", // longer than require("@paralleldrive/cuid2").bigLength
  ];
  for (const s of validStrings) {
    cuid2.parse(s);
  }

  const invalidStrings = [
    "", // empty string
    "tz4a98xxat96iws9zMbrgj3a", // include uppercase
    "tz4a98xxat96iws-zmbrgj3a", // involve symbols
  ];
  const results = invalidStrings.map((s) => cuid2.safeParse(s));
  expect(results.every((r) => !r.success)).toEqual(true);
  if (!results[0].success) {
    expect(results[0].error.issues[0].message).toEqual("Invalid cuid2");
  }
});

test("ulid", () => {
  const ulid = z.string().ulid();
  ulid.parse("01ARZ3NDEKTSV4RRFFQ69G5FAV");
  const result = ulid.safeParse("invalidulid");
  expect(result).toMatchObject({ success: false });
  const tooLong = "01ARZ3NDEKTSV4RRFFQ69G5FAVA";
  expect(ulid.safeParse(tooLong)).toMatchObject({ success: false });

  const caseInsensitive = ulid.safeParse("01arZ3nDeKTsV4RRffQ69G5FAV");
  expect(caseInsensitive.success).toEqual(true);

  // first char is capped at 7: the spec's largest ULID is 7ZZZZZZZZZZZZZZZZZZZZZZZZZ, so 8-9 and every letter overflow 2^48-1
  expect(ulid.safeParse("7ZZZZZZZZZZZZZZZZZZZZZZZZZ").success).toEqual(true);
  for (const first of ["8", "9", "A", "Z", "z"]) {
    expect(ulid.safeParse(`${first}AAAAAAAAAAAAAAAAAAAAAAAAA`).success).toEqual(false);
  }

  expect(result.error!.issues[0].message).toEqual("Invalid ULID");
  expect(result.error).toMatchInlineSnapshot(`
    [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "ulid",
        "pattern": "/^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$/",
        "path": [],
        "message": "Invalid ULID"
      }
    ]]
  `);
});

test("xid", () => {
  const xid = z.string().xid();
  xid.parse("9m4e2mr0ui3e8a215n4g");
  const result = xid.safeParse("invalidxid");
  expect(result).toMatchObject({ success: false });

  expect(result.error!.issues[0].message).toEqual("Invalid XID");
  expect(result.error).toMatchInlineSnapshot(`
    [ZodError: [
      {
        "origin": "string",
        "code": "invalid_format",
        "format": "xid",
        "pattern": "/^[0-9a-vA-V]{20}$/",
        "path": [],
        "message": "Invalid XID"
      }
    ]]
  `);
});

test("ksuid", () => {
  const ksuid = z.string().ksuid();
  ksuid.parse("0o0t9hkGxgFLtd3lmJ4TSTeY0Vb");
  const result = ksuid.safeParse("invalidksuid");
  expect(result).toMatchObject({ success: false });
  const tooLong = "0o0t9hkGxgFLtd3lmJ4TSTeY0VbA";
  expect(ksuid.safeParse(tooLong)).toMatchObject({ success: false });
  expect(result.error!.issues).toMatchInlineSnapshot(`
    [
      {
        "code": "invalid_format",
        "format": "ksuid",
        "message": "Invalid KSUID",
        "origin": "string",
        "path": [],
        "pattern": "/^[A-Za-z0-9]{27}$/",
      },
    ]
  `);
});

test("regex", () => {
  z.string()
    .regex(/^moo+$/)
    .parse("mooooo");
  expect(() => z.string().uuid().parse("purr")).toThrow();
});

test("regexp error message", () => {
  const result = z
    .string()
    .regex(/^moo+$/)
    .safeParse("boooo");
  expect(result.error!.issues).toMatchInlineSnapshot(`
    [
      {
        "code": "invalid_format",
        "format": "regex",
        "message": "Invalid string: must match pattern /^moo+$/",
        "origin": "string",
        "path": [],
        "pattern": "/^moo+$/",
      },
    ]
  `);

  expect(() => z.string().uuid().parse("purr")).toThrow();
});

test("regexp error custom message", () => {
  const result = z
    .string()
    .regex(/^moo+$/, { message: "Custom error message" })
    .safeParse("boooo");
  expect(result.error!.issues).toMatchInlineSnapshot(`
    [
      {
        "code": "invalid_format",
        "format": "regex",
        "message": "Custom error message",
        "origin": "string",
        "path": [],
        "pattern": "/^moo+$/",
      },
    ]
  `);

  expect(() => z.string().uuid().parse("purr")).toThrow();
});

test("regex lastIndex reset", () => {
  const schema = z.string().regex(/^\d+$/g);
  expect(schema.safeParse("123").success).toEqual(true);
  expect(schema.safeParse("123").success).toEqual(true);
  expect(schema.safeParse("123").success).toEqual(true);
  expect(schema.safeParse("123").success).toEqual(true);
  expect(schema.safeParse("123").success).toEqual(true);
});

test("format", () => {
  expect(z.string().email().format).toEqual("email");
  expect(z.string().url().format).toEqual("url");
  expect(z.string().jwt().format).toEqual("jwt");
  expect(z.string().emoji().format).toEqual("emoji");
  expect(z.string().guid().format).toEqual("guid");
  expect(z.string().uuid().format).toEqual("uuid");
  expect(z.string().uuidv4().format).toEqual("uuid");
  expect(z.string().uuidv6().format).toEqual("uuid");
  expect(z.string().uuidv7().format).toEqual("uuid");
  expect(z.string().nanoid().format).toEqual("nanoid");
  expect(z.string().guid().format).toEqual("guid");
  expect(z.string().cuid().format).toEqual("cuid");
  expect(z.string().cuid2().format).toEqual("cuid2");
  expect(z.string().ulid().format).toEqual("ulid");
  expect(z.string().base64().format).toEqual("base64");
  // expect(z.string().jsonString().format).toEqual("json_string");
  // expect(z.string().json().format).toEqual("json_string");
  expect(z.string().xid().format).toEqual("xid");
  expect(z.string().ksuid().format).toEqual("ksuid");
  // expect(z.string().ip().format).toEqual("ip");
  expect(z.string().ipv4().format).toEqual("ipv4");
  expect(z.string().ipv6().format).toEqual("ipv6");
  expect(z.string().e164().format).toEqual("e164");
  expect(z.string().datetime().format).toEqual("datetime");
  expect(z.string().date().format).toEqual("date");
  expect(z.string().time().format).toEqual("time");
  expect(z.string().duration().format).toEqual("duration");

  expect(z.mac().format).toEqual("mac");
});

test("min max getters", () => {
  expect(z.string().min(5).minLength).toEqual(5);
  expect(z.string().min(5).min(10).minLength).toEqual(10);
  expect(z.string().minLength).toEqual(null);

  expect(z.string().max(5).maxLength).toEqual(5);
  expect(z.string().max(5).max(1).maxLength).toEqual(1);
  expect(z.string().max(5).max(10).maxLength).toEqual(5);
  expect(z.string().maxLength).toEqual(null);
});

test("boundary cases with zero length", () => {
  // Test length(0) - only empty string should pass
  const lengthZero = z.string().length(0);
  expect(lengthZero.parse("")).toEqual("");
  expect(() => lengthZero.parse("a")).toThrow();

  // Test min(0) - all strings including empty should pass
  const minZero = z.string().min(0);
  expect(minZero.parse("")).toEqual("");
  expect(minZero.parse("a")).toEqual("a");
  expect(minZero.parse("hello")).toEqual("hello");

  // Test max(0) - only empty string should pass
  const maxZero = z.string().max(0);
  expect(maxZero.parse("")).toEqual("");
  expect(() => maxZero.parse("a")).toThrow();
  expect(() => maxZero.parse("hello")).toThrow();
});

test("length checks count Unicode code points, not UTF-16 code units", () => {
  // "\u{1F600}" is one code point but two UTF-16 code units
  const five = "\u{1F600}\u{1F600}\u{1F600}\u{1F600}\u{1F600}";
  expect(z.string().max(5).safeParse(five).success).toBe(true);
  expect(
    z
      .string()
      .max(5)
      .safeParse(five + "\u{1F600}").success
  ).toBe(false);
  expect(z.string().min(5).safeParse(five).success).toBe(true);
  expect(z.string().min(5).safeParse("\u{1F600}\u{1F600}\u{1F600}\u{1F600}").success).toBe(false);
  expect(z.string().length(5).safeParse(five).success).toBe(true);
  expect(z.string().length(1).safeParse("\u{1F600}").success).toBe(true);
  expect(z.string().nonempty().safeParse("\u{1F600}").success).toBe(true);

  // code points, not graphemes: a combining mark and a ZWJ sequence each stay several
  expect(z.string().length(2).safeParse("e\u0301").success).toBe(true);
  expect(z.string().length(3).safeParse("\u{1F9D1}\u200D\u{1F37C}").success).toBe(true);

  // an unpaired surrogate is its own code point
  expect(z.string().length(1).safeParse("\uD83D").success).toBe(true);
  expect(z.string().length(2).safeParse("\uDE00\uD83D").success).toBe(true);

  // the reported bound is still the declared one
  expect(
    z
      .string()
      .max(5)
      .safeParse(five + "\u{1F600}").error!.issues[0]
  ).toMatchObject({
    code: "too_big",
    maximum: 5,
    origin: "string",
  });

  // other lengthables keep counting elements
  expect(z.array(z.string()).max(2).safeParse(["a", "b", "c"]).success).toBe(false);
  expect(z.array(z.string()).length(2).safeParse(["\u{1F600}", "\u{1F600}"]).success).toBe(true);
});

test("trim", () => {
  expect(z.string().trim().min(2).parse(" 12 ")).toEqual("12");

  // ordering of methods is respected
  expect(z.string().min(2).trim().parse(" 1 ")).toEqual("1");
  expect(() => z.string().trim().min(2).parse(" 1 ")).toThrow();
});

test("lowerCase", () => {
  expect(z.string().toLowerCase().parse("ASDF")).toEqual("asdf");
  expect(z.string().toUpperCase().parse("asdf")).toEqual("ASDF");
});

test("slugify", () => {
  expect(z.string().slugify().parse("Hello World")).toEqual("hello-world");
  expect(z.string().slugify().parse("  Hello   World  ")).toEqual("hello-world");
  expect(z.string().slugify().parse("Hello@World#123")).toEqual("helloworld123");
  expect(z.string().slugify().parse("Hello-World")).toEqual("hello-world");
  expect(z.string().slugify().parse("Hello_World")).toEqual("hello-world");
  expect(z.string().slugify().parse("---Hello---World---")).toEqual("hello-world");
  expect(z.string().slugify().parse("Hello  World")).toEqual("hello-world");
  expect(z.string().slugify().parse("Hello!@#$%^&*()World")).toEqual("helloworld");

  // can be used with check
  expect(z.string().check(z.slugify()).parse("Hello World")).toEqual("hello-world");

  // can be chained with other methods
  expect(z.string().slugify().min(5).parse("Hello World")).toEqual("hello-world");
  expect(() => z.string().slugify().min(20).parse("Hello World")).toThrow();
});

// test("IP validation", () => {
//   const ipSchema = z.string().ip();

//   // General IP validation (accepts both v4 and v6)
//   expect(ipSchema.safeParse("114.71.82.94").success).toBe(true);
//   expect(ipSchema.safeParse("0.0.0.0").success).toBe(true);
//   expect(ipSchema.safeParse("37.85.236.115").success).toBe(true);
//   expect(ipSchema.safeParse("1e5e:e6c8:daac:514b:114b:e360:d8c0:682c").success).toBe(true);
//   expect(ipSchema.safeParse("9d4:c956:420f:5788:4339:9b3b:2418:75c3").success).toBe(true);
//   expect(ipSchema.safeParse("a6ea::2454:a5ce:94.105.123.75").success).toBe(true);
//   expect(ipSchema.safeParse("474f:4c83::4e40:a47:ff95:0cda").success).toBe(true);
//   expect(ipSchema.safeParse("d329:0:25b4:db47:a9d1:0:4926:0000").success).toBe(true);
//   expect(ipSchema.safeParse("e48:10fb:1499:3e28:e4b6:dea5:4692:912c").success).toBe(true);

//   expect(ipSchema.safeParse("d329:1be4:25b4:db47:a9d1:dc71:4926:992c:14af").success).toBe(false);
//   expect(ipSchema.safeParse("d5e7:7214:2b78::3906:85e6:53cc:709:32ba").success).toBe(false);
//   expect(ipSchema.safeParse("8f69::c757:395e:976e::3441").success).toBe(false);
//   expect(ipSchema.safeParse("54cb::473f:d516:0.255.256.22").success).toBe(false);
//   expect(ipSchema.safeParse("54cb::473f:d516:192.168.1").success).toBe(false);
//   expect(ipSchema.safeParse("256.0.4.4").success).toBe(false);
//   expect(ipSchema.safeParse("-1.0.555.4").success).toBe(false);
//   expect(ipSchema.safeParse("0.0.0.0.0").success).toBe(false);
//   expect(ipSchema.safeParse("1.1.1").success).toBe(false);
// });

test("IPv4 validation", () => {
  const ipv4 = z.string().ipv4();

  // Valid IPv4 addresses
  expect(ipv4.safeParse("114.71.82.94").success).toBe(true);
  expect(ipv4.safeParse("0.0.0.0").success).toBe(true);
  expect(ipv4.safeParse("37.85.236.115").success).toBe(true);
  expect(ipv4.safeParse("192.168.0.1").success).toBe(true);
  expect(ipv4.safeParse("255.255.255.255").success).toBe(true);
  expect(ipv4.safeParse("1.2.3.4").success).toBe(true);

  // Invalid IPv4 addresses
  expect(ipv4.safeParse("256.0.4.4").success).toBe(false);
  expect(ipv4.safeParse("-1.0.555.4").success).toBe(false);
  expect(ipv4.safeParse("0.0.0.0.0").success).toBe(false);
  expect(ipv4.safeParse("1.1.1").success).toBe(false);
  expect(ipv4.safeParse("1e5e:e6c8:daac:514b:114b:e360:d8c0:682c").success).toBe(false);
  expect(ipv4.safeParse("a6ea::2454:a5ce:94.105.123.75").success).toBe(false);
  expect(ipv4.safeParse("not an ip").success).toBe(false);
  expect(ipv4.safeParse("1.2.3").success).toBe(false);
  expect(ipv4.safeParse("1.2.3.4.5").success).toBe(false);
  expect(ipv4.safeParse("1.2.3.256").success).toBe(false);

  // Test specific error
  expect(() => ipv4.parse("6097:adfa:6f0b:220d:db08:5021:6191:7990")).toThrow();
});

test("IPv6 validation", () => {
  const ipv6 = z.string().ipv6();

  // Valid IPv6 addresses
  expect(ipv6.safeParse("1e5e:e6c8:daac:514b:114b:e360:d8c0:682c").success).toBe(true);
  expect(ipv6.safeParse("9d4:c956:420f:5788:4339:9b3b:2418:75c3").success).toBe(true);
  expect(ipv6.safeParse("a6ea::2454:a5ce:94.105.123.75").success).toBe(true);
  expect(ipv6.safeParse("474f:4c83::4e40:a47:ff95:0cda").success).toBe(true);
  expect(ipv6.safeParse("d329:0:25b4:db47:a9d1:0:4926:0000").success).toBe(true);
  expect(ipv6.safeParse("e48:10fb:1499:3e28:e4b6:dea5:4692:912c").success).toBe(true);
  expect(ipv6.safeParse("::1").success).toBe(true);
  expect(ipv6.safeParse("2001:db8::").success).toBe(true);
  expect(ipv6.safeParse("2001:0db8:85a3:0000:0000:8a2e:0370:7334").success).toBe(true);
  expect(ipv6.safeParse("2001:db8::192.168.0.1").success).toBe(true);
  expect(ipv6.safeParse("::ffff:192.168.0.1").success).toBe(true);
  expect(ipv6.safeParse("::ffff:c000:0280").success).toBe(true); // IPv4-mapped IPv6 address
  expect(ipv6.safeParse("64:ff9b::192.168.0.1").success).toBe(true); // IPv4/IPv6 translation

  // Invalid IPv6 addresses
  expect(ipv6.safeParse("d329:1be4:25b4:db47:a9d1:dc71:4926:992c:14af").success).toBe(false);
  expect(ipv6.safeParse("d5e7:7214:2b78::3906:85e6:53cc:709:32ba").success).toBe(false);
  expect(ipv6.safeParse("8f69::c757:395e:976e::3441").success).toBe(false);
  expect(ipv6.safeParse("54cb::473f:d516:0.255.256.22").success).toBe(false);
  expect(ipv6.safeParse("54cb::473f:d516:192.168.1").success).toBe(false);
  expect(ipv6.safeParse("114.71.82.94").success).toBe(false);
  expect(ipv6.safeParse("not an ip").success).toBe(false);
  expect(ipv6.safeParse("g123::1234:5678").success).toBe(false);

  // Test specific error
  expect(() => ipv6.parse("254.164.77.1")).toThrow();
});

test("MAC validation", () => {
  const mac = z.mac();

  // Valid MAC addresses
  expect(mac.safeParse("00:1A:2B:3C:4D:5E").success).toBe(true);
  expect(mac.safeParse("FF:FF:FF:FF:FF:FF").success).toBe(true);
  expect(mac.safeParse("00:11:22:33:44:55").success).toBe(true);
  expect(mac.safeParse("A1:B2:C3:D4:E5:F6").success).toBe(true);
  expect(mac.safeParse("10:20:30:40:50:60").success).toBe(true);
  expect(mac.safeParse("0a:1b:2c:3d:4e:5f").success).toBe(true);
  expect(mac.safeParse("12:34:56:78:9A:BC").success).toBe(true);

  // Invalid MAC addresses
  expect(mac.safeParse("00:1A-2B:3C-4D:5E").success).toBe(false);
  expect(mac.safeParse("00:1A:2B:3C:4D").success).toBe(false);
  expect(mac.safeParse("00:1A:2B:3C:4D").success).toBe(false);
  expect(mac.safeParse("00-1A-2B-3C-4D").success).toBe(false);
  expect(mac.safeParse("01-23-45-67-89-AB").success).toBe(false); // Dash delimiter not accepted by default
  expect(mac.safeParse("AA-BB-CC-DD-EE-FF").success).toBe(false); // Dash delimiter not accepted by default
  expect(mac.safeParse("DE-AD-BE-EF-00-01").success).toBe(false); // Dash delimiter not accepted by default
  expect(mac.safeParse("98-76-54-32-10-FF").success).toBe(false); // Dash delimiter not accepted by default
  expect(mac.safeParse("00:1A:2B:3C:4D:GZ").success).toBe(false);
  expect(mac.safeParse("00:1A:2B:3C:4D:5E:GG").success).toBe(false);
  expect(mac.safeParse("123:45:67:89:AB:CD").success).toBe(false);
  expect(mac.safeParse("00--1A:2B:3C:4D:5E").success).toBe(false);
  expect(mac.safeParse("00:1A::2B:3C:4D:5E").success).toBe(false);
  expect(mac.safeParse("00:1A:2B:3C:3C:2B:1A:00").success).toBe(false); // Disallow EUI-64
  expect(mac.safeParse("00:1a:2B:3c:4D:5e").success).toBe(false); // Disallow mixed-case

  // MAC formats that are nonstandard but occassionally referenced, ex. https://www.postgresql.org/docs/17/datatype-net-types.html#DATATYPE-MACADDR
  expect(mac.safeParse("00:1A:2B:3C:4D:5E:FF").success).toBe(false);
  expect(mac.safeParse("001A2B:3C4D5E").success).toBe(false);
  expect(mac.safeParse("001A:2B3C:4D5E").success).toBe(false);
  expect(mac.safeParse("001A.2B3C.4D5E").success).toBe(false);
  expect(mac.safeParse("001A2B3C4D5E").success).toBe(false);
  expect(mac.safeParse("00.1A.2B.3C.4D.5E").success).toBe(false);
});

test("MAC validation with custom delimiter", () => {
  const colonMac = z.mac({ delimiter: ":" });
  expect(colonMac.safeParse("00:1A:2B:3C:4D:5E").success).toBe(true);
  expect(colonMac.safeParse("00-1A-2B-3C-4D-5E").success).toBe(false);

  const dashMac = z.mac({ delimiter: "-" });
  expect(dashMac.safeParse("00-1A-2B-3C-4D-5E").success).toBe(true);
  expect(dashMac.safeParse("00:1A:2B:3C:4D:5E").success).toBe(false);

  const colonOnlyMac = z.mac({ delimiter: ":" });
  expect(colonOnlyMac.safeParse("00:1A:2B:3C:4D:5E").success).toBe(true);
  expect(colonOnlyMac.safeParse("00-1A-2B-3C-4D-5E").success).toBe(false);
});

test("CIDR v4 validation", () => {
  const cidrV4 = z.string().cidrv4();

  // Valid CIDR v4 addresses
  expect(cidrV4.safeParse("192.168.0.0/24").success).toBe(true);
  expect(cidrV4.safeParse("10.0.0.0/8").success).toBe(true);
  expect(cidrV4.safeParse("172.16.0.0/12").success).toBe(true);
  expect(cidrV4.safeParse("0.0.0.0/0").success).toBe(true);
  expect(cidrV4.safeParse("255.255.255.255/32").success).toBe(true);

  // Invalid CIDR v4 addresses
  expect(cidrV4.safeParse("192.168.0.0").success).toBe(false); // Missing prefix
  expect(cidrV4.safeParse("192.168.0.0/33").success).toBe(false); // Invalid prefix length
  expect(cidrV4.safeParse("256.0.0.0/24").success).toBe(false); // Invalid IP
  expect(cidrV4.safeParse("192.168.0.0/-1").success).toBe(false); // Negative prefix length
  expect(cidrV4.safeParse("not a cidr").success).toBe(false); // Invalid format
});

test("CIDR v6 validation", () => {
  const cidrV6 = z.string().cidrv6();

  // Valid CIDR v6 addresses
  expect(cidrV6.safeParse("2001:db8::/32").success).toBe(true);
  expect(cidrV6.safeParse("::/0").success).toBe(true);
  expect(cidrV6.safeParse("fe80::/10").success).toBe(true);
  expect(cidrV6.safeParse("::1/128").success).toBe(true);
  expect(cidrV6.safeParse("2001:0db8:85a3::/64").success).toBe(true);
  expect(cidrV6.safeParse("2001:db8:1::/48").success).toBe(true);
  expect(cidrV6.safeParse("2001:db8:85a3::8a2e:370:7334/64").success).toBe(true);
  expect(cidrV6.safeParse("2001:db8:85a3:0:0:8a2e:370:7334/64").success).toBe(true);

  const pattern = new RegExp(z.toJSONSchema(cidrV6).pattern as string);
  for (const input of ["2001:db8::/32", "2001:db8:1::/48", "2001:0db8:85a3::/64", "fe80::/10", "::/0"]) {
    expect(pattern.test(input)).toBe(true);
  }

  // Invalid CIDR v6 addresses
  expect(cidrV6.safeParse("2001:db8::").success).toBe(false); // Missing prefix
  expect(cidrV6.safeParse("2001:db8::/129").success).toBe(false); // Invalid prefix length
  expect(cidrV6.safeParse("2001:db8::/abc").success).toBe(false); // Invalid prefix format
  expect(cidrV6.safeParse("not a cidr").success).toBe(false); // Invalid format
  expect(cidrV6.safeParse("192.168.0.0/24").success).toBe(false); // IPv4 CIDR in v6 validation
  expect(cidrV6.safeParse("2001:0db8:85a3::/64/whatever-after").success).toBe(false);
  expect(cidrV6.safeParse("22d9:f4a8:6a90:f3bf:dcaa:2beb:5fba:0000/112").success).toBe(true);
  expect(cidrV6.safeParse("22d9:f4a8:6a90:f3bf:dcaa:2beb:5fba:0000/112/268").success).toBe(false);
});

test("E.164 validation", () => {
  const e164Number = z.string().e164();
  expect(e164Number.safeParse("+1555555").success).toBe(true);

  const validE164Numbers = [
    "+1555555", // min-length (7 digits + '+')
    "+15555555",
    "+155555555",
    "+1555555555",
    "+15555555555",
    "+155555555555",
    "+1555555555555",
    "+15555555555555",
    "+155555555555555",
    "+105555555555555",
    "+100555555555555", // max-length (15 digits + '+')
  ];

  const invalidE164Numbers = [
    "", // empty
    "+", // only plus sign
    "-", // wrong sign
    " 555555555", // starts with space
    "555555555", // missing plus sign
    "+1 555 555 555", // space after plus sign
    "+1555 555 555", // space between numbers
    "+1555+555", // multiple plus signs
    "+0000000", // leading zero country code
    "+0123456789", // leading zero with more digits
    "+1555555555555555", // too long
    "+115abc55", // non numeric characters in number part
    "+1555555 ", // space after number
  ];

  expect(validE164Numbers.every((number) => e164Number.safeParse(number).success)).toBe(true);
  expect(invalidE164Numbers.every((number) => e164Number.safeParse(number).success === false)).toBe(true);
});

test("hostname", () => {
  const hostname = z.hostname();

  // Valid hostnames
  hostname.parse("localhost");
  hostname.parse("example.com");
  hostname.parse("sub.example.com");
  hostname.parse("a-b-c.example.com");
  hostname.parse("123.example.com");
  hostname.parse("example-123.com");
  hostname.parse("example-123.1234");
  hostname.parse("developer.mozilla.org");
  hostname.parse("hello.world.example.com");
  hostname.parse("www.google.com");
  hostname.parse("192.168.1.1");
  hostname.parse("xn--d1acj3b.com");
  hostname.parse("xn--d1acj3b.org");
  hostname.parse("xn--d1acj3b");

  // Invalid hostnames
  expect(() => hostname.parse("")).toThrow();
  expect(() => hostname.parse("example..com")).toThrow();
  expect(() => hostname.parse("example-.com")).toThrow();
  expect(() => hostname.parse("-example.com")).toThrow();
  expect(() => hostname.parse("example.com-")).toThrow();
  expect(() => hostname.parse("example_com")).toThrow();
  expect(() => hostname.parse("example.com:8080")).toThrow();
  expect(() => hostname.parse("http://example.com")).toThrow();
  expect(() => hostname.parse("ht!tp://invalid.com")).toThrow();

  expect(() => hostname.parse("xn--d1acj3b..com")).toThrow();
  expect(() => hostname.parse("ex@mple.com")).toThrow();
  expect(() => hostname.parse("[2001:db8::zzzz]")).toThrow();
  expect(() => hostname.parse("exa mple.com")).toThrow();
  expect(() => hostname.parse("-example.com")).toThrow();
  expect(() => hostname.parse("example..com")).toThrow();
});

test("currency code", () => {
  const currency = z.currencyCode();
  for (const code of ["USD", "EUR", "XXX", "XCG", "XAD"]) expect(currency.parse(code)).toBe(code);
  for (const input of ["", "usd", "US", "USDX", " USD", "ANG", "BGN"])
    expect(currency.safeParse(input).success).toBe(false);
  expect(currency.safeParse("usd").error!.issues[0]).toMatchObject({
    code: "invalid_format",
    format: "currency_code",
    message: "Invalid currency code",
  });
});

test("hash validation", () => {
  // MD5 tests
  const md5hex = z.hash("md5");
  const md5base64 = z.hash("md5", { enc: "base64" });
  const md5base64url = z.hash("md5", { enc: "base64url" });

  // Valid MD5 hashes
  expect(md5hex.parse("5d41402abc4b2a76b9719d911017c592")).toBe("5d41402abc4b2a76b9719d911017c592");
  expect(md5hex.parse("5D41402ABC4B2A76B9719D911017C592")).toBe("5D41402ABC4B2A76B9719D911017C592"); // uppercase
  expect(md5base64.parse("XUFAKrxLKna5cZ2REBfFkg==")).toBe("XUFAKrxLKna5cZ2REBfFkg==");
  expect(md5base64url.parse("XUFAKrxLKna5cZ2REBfFkg")).toBe("XUFAKrxLKna5cZ2REBfFkg");

  // Invalid MD5 hashes
  expect(() => md5hex.parse("5d41402abc4b2a76b9719d911017c59")).toThrow(); // too short
  expect(() => md5hex.parse("5d41402abc4b2a76b9719d911017c592x")).toThrow(); // too long
  expect(() => md5base64.parse("XUFAKrxLKna5cZ2REBfFkg=")).toThrow(); // wrong padding
  expect(() => md5base64url.parse("XUFAKrxLKna5cZ2REBfFkg=")).toThrow(); // has padding

  // SHA1 tests
  const sha1hex = z.hash("sha1");
  const sha1base64 = z.hash("sha1", { enc: "base64" });
  const sha1base64url = z.hash("sha1", { enc: "base64url" });

  // Valid SHA1 hashes
  expect(sha1hex.parse("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d")).toBe("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d");
  expect(sha1base64.parse("qvTGHdzF6KLavt4PO0gs2a6pQ00=")).toBe("qvTGHdzF6KLavt4PO0gs2a6pQ00=");
  expect(sha1base64url.parse("qvTGHdzF6KLavt4PO0gs2a6pQ00")).toBe("qvTGHdzF6KLavt4PO0gs2a6pQ00");

  // SHA256 tests
  const sha256hex = z.hash("sha256");
  const sha256base64 = z.hash("sha256", { enc: "base64" });
  const sha256base64url = z.hash("sha256", { enc: "base64url" });

  // Valid SHA256 hashes
  expect(sha256hex.parse("2cf24dba4f21d4288094c4a2e2c2d6c6b0c3e0c8f0e0c8f0e0c8f0e0c8f0e0c8")).toBe(
    "2cf24dba4f21d4288094c4a2e2c2d6c6b0c3e0c8f0e0c8f0e0c8f0e0c8f0e0c8"
  );
  expect(sha256base64.parse("LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=")).toBe(
    "LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="
  );
  expect(sha256base64url.parse("LPJNul-wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ")).toBe(
    "LPJNul-wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ"
  );

  // SHA384 tests (no padding in base64)
  const sha384hex = z.hash("sha384");
  const sha384base64 = z.hash("sha384", { enc: "base64" });

  expect(
    sha384hex.parse("59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f")
  ).toBe("59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f");
  expect(sha384base64.parse("WeF0h3dEjGneawDXozO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP")).toBe(
    "WeF0h3dEjGneawDXozO7+5/xtGPkQ1TDVTvNucZm+pASWjx5+QOXvfX2oT3oKGhP"
  );

  // SHA512 tests
  const sha512hex = z.hash("sha512");
  const sha512base64 = z.hash("sha512", { enc: "base64" });

  expect(
    sha512hex.parse(
      "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"
    )
  ).toBe(
    "9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043"
  );
  expect(
    sha512base64.parse("m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==")
  ).toBe("m3HSJL1i83hdltRq0+o9czGb+8KJDKra4t/3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==");

  // Test default encoding (hex)
  const defaultHash = z.hash("sha256");
  expect(defaultHash.parse("2cf24dba4f21d4288094c4a2e2c2d6c6b0c3e0c8f0e0c8f0e0c8f0e0c8f0e0c8")).toBe(
    "2cf24dba4f21d4288094c4a2e2c2d6c6b0c3e0c8f0e0c8f0e0c8f0e0c8f0e0c8"
  );

  // Test with custom error message
  const hashWithMessage = z.hash("md5", { message: "Invalid MD5 hash" });
  expect(() => hashWithMessage.parse("invalid")).toThrow("Invalid MD5 hash");
});