feat: 增强SaaS后端功能与安全性

refactor: 重构数据库连接使用PostgreSQL替代SQLite
feat(auth): 增加JWT验证的audience和issuer检查
feat(crypto): 添加AES-256-GCM字段加密支持
feat(api): 集成utoipa实现OpenAPI文档
fix(admin): 修复配置项表单验证逻辑
style: 统一代码格式与类型定义
docs: 更新技术栈文档说明PostgreSQL
This commit is contained in:
iven
2026-03-31 00:12:53 +08:00
parent 4d8d560d1f
commit 44256a511c
177 changed files with 9731 additions and 948 deletions

View File

@@ -0,0 +1 @@
rn_("FQRAAACDXwBzAHQAdQB2AHcAeAB5AHoAc2AAewB8AH0AfgB/AIAAgQBzTQBkAGUAZgBnAGgAaQBqAAytAAJtAGZpcHN0CABbAA==")

View File

@@ -0,0 +1 @@
rn_("dQBAAAByhACSAJMAlACVAJYAlwCYAG1CAE4ATwBQAFEAUgBTAFQAQUAAAJAAogCjAK0AswD7AnJ3IUIAAKcAtAC2APsCZW8=")

View File

@@ -0,0 +1 @@
rn_("BQHAAAAKtQACkQBlaVFGAAClAK4ArwCwALEAsgCnAACFoFAAAAC1oJAAAACzoHAAAACrAsAG9EoAAAABAAwAAQA=")

View File

@@ -0,0 +1 @@
rn_("dQBAAAByhACSAJMAlACVAJYAlwCYAG1CAE4ATwBQAFEAUgBTAFQAQUAAAJAAogCjAK0AswABAAGgYAAAAKRyOzAAAAEAABEABAAfAAAAJgAHAF8AAABzAAcA+wNtcnc=")

View File

@@ -0,0 +1 @@
rn_("dQFAAAByhACSAJMAlACVAJYAlwCYAFJeAG4AbwBwAHEAcgBtbkIATgBPAFAAUQBSAFMAVAAFAEQAAAe3AGSfAFFDAAClAK4ArwCwALEAsgDzgQJpdAUBQQAAAWMAB6MAcnUkAAUAQAAAY2sAigCLAIwAjQCOAI8AciAAKwKgMAAAAKttdHUAQgAAcoQAkgCTAJQAlQCWAJcAmABtQgBOAE8AUABRAFIAUwBUACFDAACCAIMAhwCjAISgEAAAAFmgUAAAAIUBEQH1kAAAABIAAQAKAAYABQLAAAAAJQAEqwBTXgBuAG8AcABxAHIAbHN3VQFBAABDmQCaAJsAnACdAFelAK4ArwCwALEAsgBpdDkAPAA9AD4APwBAAAEAAaBgAAAApHI7MAAAAQAAEQAEAB8AAAAmAAcAXwAAAHMABwAFAcAAABFcAJ4AEqoAtwBlaQEAjaBAAAAAbWRBVk6hx6BgAAAAnqBAAAAAYqAAAAAAJWJv9PaXLw0csInIvjkW/rsltmfsxlIz6xdUJGJCF0X6vsIHLBPi/tc7YAxrmNMNQxp5HzswAAABAAAUAAUAIQAAAC4ABgBgAAAAewAGAJkABAA=")

View File

@@ -0,0 +1 @@
rn_("NQBAAAAAqQBzRQBGAFoAYQBVAUIAAEOZAJoAmwCcAJ0AV6UArgCvALAAsQCyAGl0OQA8AD0APgA/AEAAIUYAAIIAgwCHAAUBwAAAAIYAE5AAowBxcmcGAIegEAAAAFugcAAAAKagAAAAAKtRSQTzHQAAAAgAhgA=")

View File

@@ -0,0 +1 @@
rn_("AQAAOzAAAAEAABQABQAhAAAALgAGAGAAAAB7AAYAmQAEAAUAQwAAB7cAZJ8AYwADoBAAAABiZW5v86cAAAANAAIA")

View File

@@ -0,0 +1 @@
rn_("NQNCAAAFtQAJswADkQAHqwBicHN0SgBLAFcAWAAFAUAAAAanAAGoAGNlOwBTAISwQACqAA2gUAAAALQARAkBCgAAAA==")

View File

@@ -0,0 +1 @@
rd_("")

View File

@@ -0,0 +1 @@
rd_("gtotp_rs")

View File

@@ -0,0 +1 @@
rd_("CkWill check that to_bytes() returns the same. One secret \xe2\x80\xa6CjWill not check for issuer and account_name equality As \xe2\x80\xa6AmNon-encoded \xe2\x80\x9craw\xe2\x80\x9d secret.CmWill create a new instance of TOTP with given parameters. \xe2\x80\xa6BnGive the ttl (in seconds) of the current tokenmInvalid host.CcHMAC-SHA1 is the default algorithm of most TOTP \xe2\x80\xa6BeCouldn\xe2\x80\x99t decode step into a number.CnTOTP holds informations as to how to generate an auth code \xe2\x80\xa6AoReturns the argument unchanged.000000BaCalls <code>U::from(self)</code>.000000AmWill sign the given timestampCnNumber of steps allowed as network delay. 1 would mean one \xe2\x80\xa6ClDuration in seconds of a step. The recommended value per \xe2\x80\xa6CmWill check if token is valid given the provided timestamp \xe2\x80\xa6BaCharacters should only be digits.CaIssuer contains invalid character <code>:</code>.CiHMAC-SHA256. Supported in theory according to yubico. \xe2\x80\xa6CiHMAC-SHA512. Supported in theory according to yubico. \xe2\x80\xa6oInvalid scheme.AcWrong base32 input.CmShared secret between client and server to validate token \xe2\x80\xa6AlSet the <code>digits</code>.CmThe number of digits composing the auth code. Per rfc-4226\xe2\x80\xa6ChAs per rfc-4226 the secret should come from a strong \xe2\x80\xa6DoTry to transform a <code>Secret::Encoded</code> into a <code>Secret::Raw</code>AfBase32 encoded secret.Cbrfc-6238 compliant set of options to create a TOTPCmThis library permits the creation of 2FA authentification \xe2\x80\xa6CiWill generate a token given the provided timestamp in \xe2\x80\xa6BmGet the inner String value as a Vec of bytes.BkTry to create a TOTP from a Rfc6238 config.AbUnknown algorithm.CkAlgorithm enum holds the three standards algorithms for \xe2\x80\xa6CmSHA-1 is the most widespread algorithm used, and for totp \xe2\x80\xa6CkReturns the timestamp of the first second for the next stepBaInvalid secret size. (Too short?)EaTry to transforms a <code>Secret::Raw</code> into a <code>Secret::Encoded</code>.DkAccount name contains invalid character <code>:</code> or couldn\xe2\x80\x99t be \xe2\x80\xa6AeInvalid base32 input.BaDigits should be between 6 and 8.CgError returned when input is not compliant to rfc-6238.BiErrors returned mostly upon decoding URL.CmWill create a new instance of TOTP from the given Rfc6238 \xe2\x80\xa6ClImplementations MUST extract a 6-digit code at a minimum \xe2\x80\xa6ChWill check if token is valid by current system time, \xe2\x80\xa6CmWill create a new instance of TOTP with given parameters. \xe2\x80\xa6AiCouldn\xe2\x80\x99t decode issuer.CjThe length of the shared secret MUST be at least 128 bits.AkIssuers should be the same.BeDifferent ways secret parsing failed.BmGenerate a token from the current system timeCnWill return the base32 representation of the secret, which \xe2\x80\xa6CnReturns the timestamp of the first second of the next step \xe2\x80\xa6AnCouldn\xe2\x80\x99t parse account name.")

View File

@@ -0,0 +1 @@
rd_("Ah[99,13,100,28,163,135,0]Ah[99,13,100,88,180,135,0]Ag[99,13,100,88,76,135,0]Ai[99,13,100,145,164,135,0]Ai[99,13,100,100,132,135,0]Ah[99,13,100,100,37,135,0]Ae[99,15,100,88,76,0,0]Cg[99,13,100,28,163,92,0,\"impl-Display-for-Rfc6238Error\"]Ce[99,13,100,28,163,59,0,\"impl-Debug-for-Rfc6238Error\"]Af[99,13,100,28,94,59,0]Ck[99,13,100,88,180,92,0,\"impl-Display-for-SecretParseError\"]Ci[99,13,100,88,180,59,0,\"impl-Debug-for-SecretParseError\"]C`[99,13,100,88,76,92,0,\"impl-Display-for-Secret\"]Bn[99,13,100,88,76,59,0,\"impl-Debug-for-Secret\"]Cf[99,13,100,145,164,59,0,\"impl-Debug-for-TotpUrlError\"]Ch[99,13,100,145,164,92,0,\"impl-Display-for-TotpUrlError\"]Ce[99,13,100,100,132,92,0,\"impl-Display-for-Algorithm\"]Cc[99,13,100,100,132,59,0,\"impl-Debug-for-Algorithm\"]Bm[99,13,100,100,37,59,0,\"impl-Debug-for-TOTP\"]Bo[99,13,100,100,37,92,0,\"impl-Display-for-TOTP\"]Ae[99,13,100,28,94,0,0]Af[99,13,100,100,37,0,0]0Ag[99,15,100,145,164,0,0]Ag[99,15,100,100,132,0,0]1Ab[99,5,100,0,0,0,0]Ag[99,13,100,28,163,32,0]Af[99,13,100,28,94,32,0]Ag[99,13,100,88,180,32,0]Af[99,13,100,88,76,32,0]Ah[99,13,100,145,164,32,0]0Ah[99,13,100,100,132,32,0]Ag[99,13,100,100,37,32,0]Ag[99,13,100,28,163,34,0]Af[99,13,100,28,94,34,0]Ag[99,13,100,88,180,34,0]Af[99,13,100,88,76,34,0]Ah[99,13,100,145,164,34,0]Ah[99,13,100,100,132,34,0]Ag[99,13,100,100,37,34,0]Af[99,13,100,100,37,0,0]Af[99,14,100,100,37,0,0]01Af[99,13,100,28,94,58,0]Ag[99,13,100,88,180,58,0]Af[99,13,100,88,76,58,0]Ah[99,13,100,100,132,58,0]Ag[99,13,100,100,37,58,0]Ag[99,15,100,145,164,0,0]0Ag[99,15,100,100,132,0,0]011Ac[99,6,100,88,0,0,0]Ag[99,13,100,28,163,67,0]Af[99,13,100,28,94,67,0]Ag[99,13,100,88,180,67,0]Af[99,13,100,88,76,67,0]Ah[99,13,100,145,164,67,0]Ah[99,13,100,100,132,67,0]Ag[99,13,100,100,37,67,0]Ae[99,13,100,28,94,0,0]Af[99,14,100,100,37,0,0]0Ae[99,13,100,88,76,0,0]Ae[99,15,100,88,76,0,0]Ac[99,5,100,28,0,0,0]Ah[99,13,100,100,132,91,0]A`[99,3,0,0,0,0,0]Af[99,13,100,28,163,9,0]Ae[99,13,100,28,94,9,0]Af[99,13,100,88,180,9,0]Ae[99,13,100,88,76,9,0]Ag[99,13,100,145,164,9,0]Ag[99,13,100,100,132,9,0]Af[99,13,100,100,37,9,0]Af[99,13,100,100,37,0,0]<Af[99,13,100,28,94,95,0]Ag[99,13,100,88,180,95,0]Af[99,13,100,88,76,95,0]Ah[99,13,100,100,132,95,0]Ag[99,13,100,100,37,95,0]Ag[99,13,100,28,163,96,0]Af[99,13,100,28,94,96,0]Ag[99,13,100,88,180,96,0]Af[99,13,100,88,76,96,0]Ah[99,13,100,145,164,96,0]Ah[99,13,100,100,132,96,0]Ag[99,13,100,100,37,96,0]0Ag[99,13,100,28,163,97,0]Af[99,13,100,28,94,97,0]Ag[99,13,100,88,180,97,0]Af[99,13,100,88,76,97,0]Ah[99,13,100,145,164,97,0]Ah[99,13,100,100,132,97,0]Ag[99,13,100,100,37,97,0]Ag[99,15,100,145,164,0,0]Ab[99,6,100,0,0,0,0]Af[99,14,100,100,37,0,0]Af[99,13,100,100,37,0,0]Ah[99,13,100,28,163,108,0]Ah[99,13,100,88,180,108,0]Ag[99,13,100,88,76,108,0]Ai[99,13,100,145,164,108,0]Ai[99,13,100,100,132,108,0]Ah[99,13,100,100,37,108,0]9Ah[99,13,100,28,163,133,0]Ag[99,13,100,28,94,133,0]Ah[99,13,100,88,180,133,0]Ag[99,13,100,88,76,133,0]Ai[99,13,100,145,164,133,0]Ai[99,13,100,100,132,133,0]Ah[99,13,100,100,37,133,0]Af[99,13,100,28,94,95,0]Ag[99,13,100,88,180,95,0]Af[99,13,100,88,76,95,0]Ah[99,13,100,100,132,95,0]Ag[99,13,100,100,37,95,0]Ae[99,13,100,88,76,0,0]Ag[99,15,100,145,164,0,0]Af[99,15,100,88,180,0,0]1Ac[99,6,100,28,0,0,0]Ad[99,6,100,145,0,0,0]Af[99,13,100,100,37,0,0]Af[99,15,100,28,163,0,0]11Ae[99,13,100,28,94,0,0]616Ag[99,13,100,28,94,166,0]Ah[99,13,100,88,180,166,0]Ag[99,13,100,88,76,166,0]Ai[99,13,100,100,132,166,0]Ah[99,13,100,100,37,166,0]Ac[99,6,100,88,0,0,0]888<")

View File

@@ -0,0 +1 @@
rd_("Ba[\"{{{AAd{ADf}}{AAd{ADf}}}Dl}\",[]]Ba[\"{{{AAd{AFh}}{AAd{AFh}}}Dl}\",[]]Ao[\"{{{AAd{Ih}}{AAd{Ih}}}Dl}\",[]]Ba[\"{{{AAd{ADh}}{AAd{ADh}}}Dl}\",[]]Ba[\"{{{AAd{A@h}}{AAd{A@h}}}Dl}\",[]]Ao[\"{{{AAd{Dj}}{AAd{Dj}}}Dl}\",[]]Bc[\"{{{AAd{ADf}}{AAd{CbA@l}}}Hl}\",[]]0Bb[\"{{{AAd{Kl}}{AAd{CbA@l}}}Hl}\",[]]Bc[\"{{{AAd{AFh}}{AAd{CbA@l}}}Hl}\",[]]0Bb[\"{{{AAd{Ih}}{AAd{CbA@l}}}Hl}\",[]]0Bc[\"{{{AAd{ADh}}{AAd{CbA@l}}}Hl}\",[]]0Bc[\"{{{AAd{A@h}}{AAd{CbA@l}}}Hl}\",[]]0Bb[\"{{{AAd{Dj}}{AAd{CbA@l}}}Hl}\",[]]0Bb[\"{{Hd{Af{A`}}}{{Hn{KlADf}}}}\",[]]Bi[\"{{A@hHdA`Cn{Af{A`}}}{{Hn{DjADh}}}}\",[]]Ba[\"{{{AAd{Dj}}}{{Hn{CnAEl}}}}\",[]]A`[\"{cc{}}\",[\"T\"]]000o[\"{ADfADh}\",[]]111Aa[\"{{}c{}}\",[\"U\"]]000000B`[\"{{{AAd{Dj}}Cn}{{Af{A`}}}}\",[]]m[\"{DjA`}\",[]]m[\"{DjCn}\",[]]Ba[\"{{{AAd{Dj}}{AAd{Cj}}Cn}Dl}\",[]]Af[\"{{{AAd{Kl}}}Kl}\",[]]Ah[\"{{{AAd{AFh}}}AFh}\",[]]Af[\"{{{AAd{Ih}}}Ih}\",[]]Ah[\"{{{AAd{A@h}}}A@h}\",[]]Af[\"{{{AAd{Dj}}}Dj}\",[]]Ak[\"{AAd{{AAd{c}}}{}}\",[\"T\"]]000000Be[\"{{{AAd{CbKl}}Hd}{{Hn{GbADf}}}}\",[]]m[\"{DjHd}\",[]]m[\"{DjAf}\",[]]Ba[\"{{{AAd{Ih}}}{{Hn{IhAFh}}}}\",[]]n[\"{{}A@h}\",[]]n[\"{AAdIl}\",[]]000000Ah[\"{{{AAd{Dj}}Cn}Ij}\",[]]Bg[\"{{{AAd{Ih}}}{{Hn{{Af{A`}}AFh}}}}\",[]]Ab[\"{AAdc{}}\",[\"T\"]]0000An[\"{c{{Hn{e}}}{}{}}\",[\"U\",\"T\"]]000000Bh[\"{Kl{{Hn{Djc}}}{}}\",[\"TryFrom::Error\"]]Ai[\"{{}{{Hn{c}}}{}}\",[\"U\"]]000000n[\"{DjA@h}\",[]]Ah[\"{{{AAd{Dj}}Cn}Cn}\",[]]n[\"{AAdIj}\",[]]00000Be[\"{{{AAd{Cb}}}{{AAd{Cbc}}}{}}\",[\"T\"]]000000Ao[\"{{AAd{AAd{Cbc}}}Gb{}}\",[\"T\"]]0000Af[\"{{{AAd{Ih}}}Ih}\",[]]Ah[\"{Kl{{Hn{DjADh}}}}\",[]]Bj[\"{{{AAd{Dj}}{AAd{Cj}}}{{Hn{DlAEl}}}}\",[]]An[\"{{A@hHdA`Cn{Af{A`}}}Dj}\",[]]B`[\"{{{Af{A`}}}{{Hn{KlADf}}}}\",[]]Aj[\"{{AAd{Lf{CbA`}}}Gb}\",[]]0000Ba[\"{{{AAd{Dj}}}{{Hn{IjAEl}}}}\",[]]Af[\"{{{AAd{Dj}}}Ij}\",[]]Ba[\"{{{AAd{Dj}}}{{Hn{CnAEl}}}}\",[]]")

View File

@@ -0,0 +1 @@
rb_("RWIAOzAAAAEAAAYAAQAuAAYAOzAAAAEAABIABAAmAAMAKwACAG4ABAB7AAYAOzAAAAEAAA0AAgBOAAYAcwAGAAF6AAAAOzAAAAEAAAsAAQCSAAsAQWIAAAA7MAAAAQAABgABAHMABgA=")

View File

@@ -0,0 +1 @@
rd_("b()beq00000bu8cAnycRawcVeccfmt000000000000cmutcnew0crfccstrcttlcu64dFromdHostdIntodSHA1dStepdTOTPdbooldfrom0000000dinto000000dsigndskewdstepduniteCloneeDebugecheckeclone0000eusizefBorrowfDigitsfIssuerfResult0fSHA256fSHA512fSchemefSecret0fStringfTypeIdfborrow000000fdigits0fsecret0fto_rawgDefaultgDisplaygEncodedgRfc6238gToOwnedgTryFromgTryIntogdefaultgpointergtotp_rsgtype_id000000hToStringhgeneratehto_byteshto_owned0000htry_from0000000htry_into000000iAlgorithm0iBorrowMutiFormatteriPartialEqialgorithminext_stepireferenceito_string00000iurl_errorjSecretSizejborrow_mut000000jclone_into0000jto_encodedkAccountNamekParseBase32lDigitsNumberlRfc6238ErrorlTotpUrlErrorlfrom_rfc6238mCloneToUninitmInvalidDigitsmcheck_currentmnew_uncheckedmwith_defaultsnIssuerDecodingnSecretTooSmalloIssuerMistmatchoSystemTimeErroroclone_to_uninit0000A`SecretParseErrorA`generate_currentAaget_secret_base32Aanext_step_currentAcAccountNameDecoding")

View File

@@ -0,0 +1 @@
rd_("b()beq00000bu8canycrawcveccfmt000000000000cmutcnew0crfccstrcttlcu64dfromdhostdintodsha1dstepdtotpdbool666666664444444dsigndskew4dunitecloneedebugecheck22222eusizefborrowfdigitsfissuerfresult0fsha256fsha512fschemefsecret0fstringftypeid99999998822etorawgdefaultgdisplaygencodedgrfc6238gtoownedgtryfromgtryinto6gpointerftotprs:::::::htostringhgenerategtobytes77777666666665555555ialgorithm0iborrowmutiformatteripartialeq3hnextstepireference888888hurlerrorjsecretsize6666666icloneinto0000itoencodedkaccountnamekparsebase32ldigitsnumberlrfc6238errorltotpurlerrorkfromrfc6238mclonetouninitminvaliddigitslcheckcurrentlnewuncheckedlwithdefaultsnissuerdecodingnsecrettoosmalloissuermistmatchosystemtimeerror88888A`secretparseerrorogeneratecurrentogetsecretbase32onextstepcurrentAcaccountnamedecoding")

View File

@@ -0,0 +1 @@
rd_("f[1,\"\"]0A`[10,\"core::any\"]Am[5,\"alloc::vec\",\"alloc::vec\"]f[0,\"\"]m[2,\"totp_rs\"]44Ad[10,\"core::convert\"]0Ag[5,\"totp_rs\",\"totp_rs\"]66Ab[10,\"core::clone\"]A`[10,\"core::fmt\"]8Ac[10,\"core::borrow\"]Ak[8,\"core::fmt\",\"core::fmt\"]Ba[6,\"core::result\",\"core::result\"]Ao[6,\"totp_rs\",\"totp_rs::secret\"]Bc[5,\"alloc::string\",\"alloc::string\"]Ak[5,\"core::any\",\"core::any\"]:Ad[10,\"core::default\"]7Al[5,\"totp_rs\",\"totp_rs::rfc\"]Ad[10,\"alloc::borrow\"]<<f[1,\"\"]f[3,\"\"]Ad[10,\"alloc::string\"]Ag[6,\"totp_rs\",\"totp_rs\"]<Ak[5,\"core::fmt\",\"core::fmt\"]A`[10,\"core::cmp\"]5m[2,\"totp_rs\"]Al[6,\"totp_rs\",\"totp_rs::rfc\"]Bb[6,\"totp_rs\",\"totp_rs::url_error\"]Ab[10,\"core::clone\"]Ak[5,\"std::time\",\"std::time\"]Ao[6,\"totp_rs\",\"totp_rs::secret\"]")

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
rd_("Bo[\"\",\"AAAAAAA7MAAAAQAACQACAJkABACuAAQAAAFVAAAA\"]Fk[\"AAAAAAA7MAAAAQAABQACAKkAAACuAAQAARkAAAABqAAAAAABGgAAAA==\",\"AAAAAAABNQAAAAFtAAAAAAAAAAAAAAAAAAABNgAAAA==\"]Eg[\"AAAAAAABqQAAAAEZAAAAAagAAAAAARoAAAA=\",\"AAAAAAABNQAAAAFtAAAAAAAAAAAAAAAAAAABWAAAAA==\"]Eo[\"AAAAAAA7MAAAAQAAEAACAJIACwCuAAQAOzAAAAEAAAwAAQALAAwAAVUAAAA=\",\"AAAAAAA7MAAAAQAABgABAJIABgA=\"]Ao[\"AAAAAAAAATsAAAABpwAAAA==\",\"\"]Fg[\"AAAAAAJsAAAAiAAAAAE1AAAAATsAAAABqAAAAAABGgAAAA==\",\"AAAAAAGIAAAAAh0AAAC2AAAAAAAAAAAAAAAAAAAAATcAAAA=\"]Jk[\"AAAAAkAAAAC1AAAAAmwAAACIAAAABQYAAAAdAAAANQAAALQAAAC2AAAAAxYAAAAXAAAAOwAAAAGnAAAAAAAAAAAAAAAAAAU2AAAANwAAAFYAAABYAAAAhwAAAA==\",\"AAAAAUAAAAACegAAAKQAAAAAAAGoAAAAAAEaAAAA\"]Bo[\"\",\"AAAAAAA7MAAAAQAABQABAAEABQABOwAAAAGnAAAA\"]7Dk[\"AAAAAAAAARkAAAACVQAAAKgAAAAAARoAAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAAAVYAAAA=\"]Bc[\"\",\"AAAAAAAAOzAAAAEAAAwAAQALAAwA\"]Gm[\"\",\"AAA7MAAAAQAABgABAHsABgA7MAAAAQAABgABAHMABgACegAAAKQAAAAFHQAAAFkAAACpAAAAtAAAALYAAAACGQAAAG0AAAACVQAAAKcAAAAAARoAAAA=\",1]Do[\"AAAAAj4AAACeAAAAAAIDAAAAWQAAAAMQAAAAEQAAAG0AAAA=\",\"AAAAAj4AAACeAAAAAAFZAAAA\"]Cc[\"\",\"AAA7MAAAAQAABQABAIoABQABtQAAAAFsAAAAAbQAAAA=\"]Ao[\"\",\"AAA7MAAAAQAABgABAGQABgA=\"]Dk[\"AAAAATwAAAACegAAAKQAAAAAAQ0AAAABVQAAAA==\",\"AAAAATwAAAAAAakAAAABGQAAAA==\"]Bm[\"AAAAAAAFrgAAAK8AAACwAAAAsQAAALIAAAA=\",\"\",1]Fc[\"AAAAAT8AAAAAAQUAAAACFAAAABUAAAABqAAAAAABGgAAAA==\",\"AAFhAAAAAAE/AAAAAAAAAAAAAAAAAAAAAAABhwAAAA==\"]Bc[\"AAAAAAAAOzAAAAEAAAwAAQALAAwA\",\"\"]Oa[\"AAA7MAAAAQAAEQADAGQABgBuAAQAigAFADswAAABAAANAAQAPAAEAE4ABgCeAAAAtQAAAAJsAAAAiAAAADswAAABAAAbAAgAAQAFAB0AAAA1AAAAWQAAAJIACwCuAAQAtAAAALYAAAA7MAAAAQAADgADAAsADAA7AAAAbQAAAAJVAAAApwAAAA==\",\"AAAAOzAAAAEAAAYAAQBOAAYAADswAAABAAAGAAEAkgAGAA==\",1]Dc[\"AAABKgAAAAAAAQEAAAACCwAAAAwAAAA=\",\"AAAAAAABqQAAAAEZAAAAAVUAAAA=\"]Dc[\"AAAAAAABBAAAAAISAAAAEwAAAA==\",\"AAABKgAAAAABpAAAAAAAAAABGgAAAA==\"]Bg[\"\",\"AAAAAAADHQAAALQAAAC2AAAAAAGnAAAA\"]Dc[\"AAAAAT0AAAAAAQIAAAACDgAAAA8AAAA=\",\"AAAAAT0AAAAAAVkAAAABbQAAAA==\"]")