diff --git a/metaschema/parser/context_parsing.go b/metaschema/parser/context_parsing.go new file mode 100644 index 0000000..8c33947 --- /dev/null +++ b/metaschema/parser/context_parsing.go @@ -0,0 +1,50 @@ +package parser + +import ( + "encoding/xml" +) + +type parentElement interface { + RegisterChild(GoStructItem) +} + +type contextParser []parentElement + +var context contextParser + +func (cp *contextParser) Push(p parentElement) { + *cp = append(*cp, p) +} + +func (cp *contextParser) Pop() { + *cp = (*cp)[:len(*cp)-1] +} + +func (cp *contextParser) RegisterChild(child GoStructItem) { + (*cp)[len(*cp)-1].RegisterChild(child) +} + +func (m *Model) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type model Model + context.Push(m) + defer context.Pop() + return d.DecodeElement((*model)(m), &start) +} + +func (m *Model) RegisterChild(child GoStructItem) { + m.sortedChilds = append(m.sortedChilds, child) +} + +func (a *Assembly) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type assembly Assembly + err := d.DecodeElement((*assembly)(a), &start) + context.RegisterChild(a) + return err +} + +func (f *Field) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + type field Field + err := d.DecodeElement((*field)(f), &start) + context.RegisterChild(f) + return err +} diff --git a/metaschema/parser/main.go b/metaschema/parser/main.go index 1c5c9b7..0d54899 100644 --- a/metaschema/parser/main.go +++ b/metaschema/parser/main.go @@ -89,21 +89,15 @@ func (Metaschema *Metaschema) ContainsRootElement() bool { } type Model struct { - Assembly []Assembly `xml:"assembly"` - Field []Field `xml:"field"` - Choice []Choice `xml:"choice"` - Prose *struct{} `xml:"prose"` + Assembly []Assembly `xml:"assembly"` + Field []Field `xml:"field"` + Choice []Choice `xml:"choice"` + Prose *struct{} `xml:"prose"` + sortedChilds []GoStructItem } func (m *Model) GoStructItems() []GoStructItem { - res := make([]GoStructItem, len(m.Assembly)+len(m.Field)) - for i, _ := range m.Field { - res[i] = &m.Field[i] - } - for i, _ := range m.Assembly { - res[i+len(m.Field)] = &m.Assembly[i] - } - return res + return m.sortedChilds } type Choice struct { diff --git a/metaschema/parser/metaschema_compile.go b/metaschema/parser/metaschema_compile.go index 8767221..387c7ba 100644 --- a/metaschema/parser/metaschema_compile.go +++ b/metaschema/parser/metaschema_compile.go @@ -24,6 +24,15 @@ func (metaschema *Metaschema) registerDependency(name string, dependency GoType) } } +func (metaschema *Metaschema) linkItems(list []GoStructItem) error { + for i, _ := range list { + err := list[i].compile(metaschema) + if err != nil { + return err + } + } + return nil +} func (metaschema *Metaschema) linkAssemblies(list []Assembly) error { for i, _ := range list { a := &list[i] @@ -63,20 +72,15 @@ func (metaschema *Metaschema) linkDefinitions() error { if err = metaschema.linkFlags(da.Flags); err != nil { return err } + if err = metaschema.linkItems(da.Model.sortedChilds); err != nil { + return err + } if err = metaschema.linkAssemblies(da.Model.Assembly); err != nil { return err } if err = metaschema.linkFields(da.Model.Field); err != nil { return err } - for _, c := range da.Model.Choice { - if err = metaschema.linkAssemblies(c.Assembly); err != nil { - return err - } - if err = metaschema.linkFields(c.Field); err != nil { - return err - } - } } for _, df := range metaschema.DefineField { diff --git a/metaschema/templates/generated_models.tmpl b/metaschema/templates/generated_models.tmpl index f555ac6..eb6ab49 100644 --- a/metaschema/templates/generated_models.tmpl +++ b/metaschema/templates/generated_models.tmpl @@ -20,19 +20,6 @@ type {{.GoTypeName}} struct { // {{ .GoComment }} {{.GoName}} {{.GoMemLayout}}{{.GoTypeNameMultiplexed}} `xml:"{{.XmlAnnotation}}" json:"{{.JsonName}},omitempty"` {{- end}} - - {{- range .Model.Choice}} - {{- range .Field}} - // {{ .GoComment }} - {{.GoName}} {{.GoMemLayout}}{{.GoTypeName}} `xml:"{{.XmlAnnotation}}" json:"{{.JsonName}},omitempty"` - {{- end}} - - {{- range .Assembly}} - // {{ .GoComment }} - {{.GoName}} {{.GoMemLayout}}{{.GoTypeName}} `xml:"{{.XmlAnnotation}}" json:"{{.JsonName}},omitempty"` - {{- end}} - - {{- end}} {{end}} } diff --git a/metaschema/templates/pkged.go b/metaschema/templates/pkged.go index 6045c95..466939c 100644 --- a/metaschema/templates/pkged.go +++ b/metaschema/templates/pkged.go @@ -9,4 +9,4 @@ import ( "github.com/markbates/pkger/pkging/mem" ) -var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec5b5b73a3bab2fe2bbb78dd5e83c0c60eaeda0fc689318ee399d889b94cad9a12200383b82c247cc9aaf9efa7246c8c1de776669df3b2f3e0a0969a5677ebeb06ba2b7f0b51baca88d0ff5b60bfeba810fa8218660912092e6348a2f88f555b167d48a158203f84540c222a86a52b0699972539de8909a29078214aa0d0128c24cf0afa0dd250e80b424b98c104097de184e73af3aac50758048856e37996ed4777907aa1d04f4b8c5bc282428c84fe0a6282f6d41c4192a515af9e8d228cc881bbdabd26af515e8f1f10a167dc6ceaec8ebbcc2fd97e7f0b7b13828886a5fbc5cb92170cbe83512af46951a2d63fe13f3dbbcbfcdf122206d99724f3b9ac252a48c47d257d91dac2af5fbf5ac2aa72c1df6f98d66f8aa428c931a48888014a510129f27f24998f30f942931c33690c48ecea230a23cc3748abb3bf7c4b4b20d11312fa524f69b704b622f43bed2e1ffea011bf530632f843027fb4c18304fa8ad497d52fddb6720514f9aafb6f20f501105a42447ef8ccf17b8c901ddffc1aad857eb7d3eb492dc14833a1df53aed4f695d41266384a63a12ff1d34642bfdd9641a7253c46bed09700002d413f0ead1f3f72e803a10f5ac2dc6732414b583434d7705c19d2016a9791991713a17fd51206344a98260be4097da90b3a40912419b4841961334aa7d7b9525470f5ab25dc5d60ed5ca907d6dae65f2d61f87e56ebc78f322d09f285fe77d0022df0270740888a7f22d82fe2e33c03bc8eb19744ec934673eab59cf15b01b7cf36df852fc29f75baa9c2f934db1046fdcb47394a7d947abbfebfde6f5c0e0b828a66befa5e5bf725c8d8ce7522fa2eb8bbca66541459c106ab840aad0ff8b2deae714b028bd8e5219cc741b59889abac4820931d6562949534627199b12d73484391a50a3660c14a8b280dd80a455b5a9f16d3bccab2df05b75c4599d0aad5672a16881071c5391b13c15394733aa5304a5121e288d0fd04daf251b1cb69560f445849ac082fca436ec19ef69b8b3e81470279a7a42f2b8aa43e9b10a394a222855844fe06163e3967c338ca69e41d67c20436a8faf602a6fede8be74ba4742946c785c4578e04bbaf41799d06d1348084503aa164a57b422b92dca0cfb6a4b8e1a7ad02d4534acce368cb60977a991fa541632842924a4dda8504753b2733510a8b5d7326444d69e24f16460d3a474993dc26f80dc8bbe56a05712686a840bf1d0e114cbd0ca304a622a18507097a335c5e5cbca0d139470d8304e6e475d63c0e2ae7bfc92312eaf3600d3211f2006a867490350ccfc4bce03a5404f1609a1e089ac5889d4c0849b8bf885ee1b519926abd5950431c34a7bcbc6c92ab8492aca0cda914515a400f35e732c2cfb83995671837e9f35b0ab4c2c8a338a227d3244a038c56380ac2935dc98e781063116d9187d2f5a5a532e548afe729221467dcbaec2c1b56d3499505d94574a3e038a4e430dec770c25e5daa8b9894984639e44ee1137f9519453e3f0ae8f2d04c11adfe8a21a57963c8ff1cbc574f1e34decfb16c991719cf948c2e8b3a8167843b609fca2f64f4bd57f92840dbbc1e88649752c8fc539429adccd98f442fc81a54ed3f48b384a7c7672b7bc73d9b676f692d610f181681193fa9e36386ec526f7f398adf9f5ffd1482eea6882a549f3e96cee82a12d86c654e99461e7bf7ab4762495752f794bee224812bc6b746a99f1562906198065fb22210b7e2e17114422f8432781f579ee19dd406ca1bdcfcc282eebd7c8714fd1a7359acd1e1d1f60a5f18fbabd7399e3fd55e617ec362865b3f25ec97204260f092b893c8084a1e796ff2e545b6ddbdc1288b610ebdf815aec84fe10bcb6447f699f0d22a4721415e5920d18dfca8285ff45605d802a684a5f0d7980e186502dfc39732797f7e7e02579fc0fb84c8ec8b83f798b7ff1af9c8f7f0af96c05415fac2747715dccb6aec2cb4d43115ec2523e098f7819dc6011ccf8137beeb4e776a0aad79e69b4669cb2a9d027f7d2fabd4d3b7ca5496b0af8f9e6c39c4ae79d3336ee6df8c1be5db72a88de637f8711ae43db49b6f6c7356d8a68f1f9211751683eeb7c5a09ccbeafdd93c5d59e0d6d3473fa13c4a9d85d643bb415cd38f4ae89a8f01e319a6b4e7c84bb030a58ddb9e006f37280ff3131d045f7f82601a55f2509bee6c53491db6a7be4ca0a9e07b6bf6e49852e48eb1babacf026378b536c6b4670c95b10b666bd794b09bdef3bdfc31de54ba2863579a2b9ebefc6a9b125e5920f0daf39d6fce803126b7c650eb211927c650593896b673ac1976d3f9d363a2aefd9b25711a328da1663f3c6eb91c631c5277a854635debb8e6a66b2421f0c703e6fb9f5e7bf2739a28b9d7be2f1d5995a7b2f23495d5275b1e91e9d34d7937e47e2a2b1f6aea6a6104309daddd9f59345d4c82613408509b50435f96ce5852998fa60bede893641b3aedd99b7ee0f6311f00760e4b7575f0099887be3e02c8d2b84f6c66cf7516a136294d5d225c2f4b52a7fa08f86383b8b294fbfa927ae3b96244da5f9eac965fa3099375cbc6477e95426b8e5d4b0388d951e98ddd645ee93aa63d68dac13496d68ebe24958e033edfb4efc15463c7dc30bc3df8e38964b7e713be7f5b52996ff83dafda5df1307be6b25a9ffd9e9e39a674675b78ed5b737565d1de34f6d74b86198ed7e5cc37b7005a1a71ac1033ffd767ccecc121756f46a59ba8c0b6e6b92b2b27e7c7f658b0717cf0f976ed9a1838a6b4f1c771640fb2836ec7f30db2177d702f876b68cef0f13c41e025a3d2911f8369ece48eb98df736afa7bb0a577359bd7665893aa6028c71e5b3ffa52f186602a44b647fdeb66b6e353751d60c3fd054590c47869e3fb972a7f24fccc6ca619f53ec2483da06c754b8de35d6c793d04d7c6c0c15cd6bcfb06b4e08b22add59ce436d1230dd581e73cd65e90fb51a536cfe80c19a3697f4411f296e7b0956967431179ce3fede544ab7cd6203afdd54523f84f5f3983d9ee909fe6bbb539ee70e6b1773de3cc1d8d5e76fc6396a93d81db21cad11c7ec305c10dbf49f8ca1a4aeee73ee6f16774efb3e98e89be06e58e5d90fe5c953dc71f9bf81bb1bdb9a877c7feb527cd5b113fae3f9eed4d71f8cb5bdcf2b5f64b52dcc1f2c868da132aae4563eb990339ffcf1247713afc6cb549f65b63589990dbf85118e014e134f5e1ef1bcd072271a940b6b36b3ad49e15b8360ba8f85e399717f3fb21c7e7c8e0c54e3460abd844adea081bff10c1fcee3f5fb6b5b9fc56985d5fb4a8fb48963da6bc4ee8d6371bc633799e58e75f7e6f3f85badcb123c984b605bb39f505f527bc178b5d09669e8c8cbfd735752a7e9851cc5302e2f4b87e784fffc877f9c1628a5c797b2e36b177f63fbdd5605ff0ec7688b8a0f362c9edd58b72d14a0bedab600ea1f92f22075fb00f43bea97ab9ea4a86aaf27ff1bc81f6e5bf4baf23fd8b6e09abfbf6dd156bb8a72d53e3418e44eb7ad4aa00d2eb42d80d4bbea74ea5e446df385b6c533d68ea2aa5740fe6c5b7cb62d3edb169f6d8bcfb6c567dbe2b36df1d9b6f86c5b7cb62d3edb169f6d8bcfb6c5ff55dbe2d927eeff67f3225b4f77da4901d74bef02db9a6043c7a5a3e39d63ce80a15705686fa7958eb98c990e4ea2ee8cf10c7b090e5d1d77abe26e87f13d39d624b7cd6d8e92aae8398caed6863e7ada173e03db54e2aa29a025d0dc626fa7c5d07412c73202d71c81fdfd042db4dc8d3400f565ee45bcd822d9edb9e4258f256f848ccf0a1ed799ca0b7ee78590bab037a7154f675f9839f03df282e93379bc3099e7aea5adbdf43eb81d4eb09bccd60ef3cd4ee5852c238a7951e758ec9324773ccf3d7d8b91bedc1d8af0af15754ce979c1f5a13dc91d1997b6b93d14e212df547e1ac39072d9c3c15ffbe2e0b1286549eaed425bba89147ae92cb3cdeded2350bfdeea06db2342d61cdf2e34eca593b51769bd637380fd8e85be698cf7854229f4c6cd2602e7936dcb08a0a93c41738e1fccd1c6d0a5d01bd17d31ccf79fe9f5a8eea0e9e76e32e24d8ce1e2288f175aadc98e9f4b858f72692ad4b6264f501f915bdd20c6d0c9dd74963bfa72665b83fceb8ed96004c60308dc0493aae8dad4f1f8f39225f0ad4969b0b308b293b5caaf0d7e7dc31b6bae392a9c45e85acf0bfcdfbc04a7d05442772ca9d3e160331df22272d6f4c7ed223e93eb307f17d3a126733b0f05401d979e8c63e7510abde1f979347e63bb3c166f294696a41ad720809bec32ff50236cddb6b48d632af1adbe21c6d8ce8741dc90094e756c143f9b4da1f39f9f8c76cc4fefc0ec4bba3df93206b61c0436261b6bf18addfa2cf4e4c760d226e9d7e025794d1b9c90e509682aa9ab2f01cb356f61f14d99432d77a20a6f0c1bbc981e298d18db6476b40926e98c619f38d67ced46718fe32d1a84df165a09cd4d805e3cab8fe3f6b2edefb2e5022e4ef47e5186a32f13db5a12ff3afbe77c966c3e14cb97ed9e607fbcdcb9d57eefd14d7d096fe7983d693e9cde93dd26d2c6d5979ddbc54035f4cded0b3ab1b3bfe57b06f94983e0ada27b5571459fff16f2dff072f9eb7f000000ffff010000ffff037a535b09340000`))) +var _ = pkger.Apply(mem.UnmarshalEmbed([]byte(`1f8b08000000000000ffec5b5b73a2cab7ff2affe2f5ef0e172506df8444c41867a2892053bba61a6881a1a1d974a3925df3dd4f75838ae63a3553a7ead4c983b1d7eac5ea75477e54fe15e26c8d8930f857609febb810068218e1148a0495092071f2d7baab8801a0402c6010012a863115a3d21343ece334479598420a881fc114081dc14a735cd0af8046c240103ac20ca45018082732d7d8af371f4011425aafe71837ab3b40fd48186425421d61410182c2600d10810d358780e0ac9635f1284690eca5ebd30fe435cc0feb0748e89934639d5d718783929df7afd0b810c6342abd0b1fa7af387c07e24c18d0a2849d3f113f13dfe1e0b7948821be4871c0752d6141621e2bf942ee0a3f7ffeec08eb3a04ffbee3daa0ad92c2344780422286308305a030f89ee200227241d31c316dac90d877002988113f20ab73fff2251d81c44f5018c8dd2bad23b01d61d0eb5ef2e5771af32b154991fe92a5bfbad283ac0c1469a0a817575db57b79a54abdff4af24092848e1093ef010b7c5323a4e2875fc38d30b8ecf5fb7247b0322c0cfaea95266b524798a1384b8481ccb30d8541b7ab48bd8ef01807c2409624a92398c7a5f3fd7b0e024918481d611e309d524758b42cd751523bd293b44b46623f21c2e0aa230c699c324b16d01706f2a5d493d4cbab6eb723cc08e3282a33ee4afbd911ee5e9254d4bde4c1e59f1dc1f8b8a8f3fd7b99950406c2e09bd4913ad2df3cff112cfe44afbf581ee703e0ed127b4d453333daacb746c66ff55b336cbe0917c2df87695377f3e9b0218cfa4f0073980530f3abc17f5acec520f3318229c844420b1f10d89e4ddf0eae5c84981d73183adf04afaa1d8445810bb658a754e8fc42e0725010589c5e928222f178bbe649586f62718d8b1430dd3116635cd298f5206647e68046221b0b6cc11a93167116b21d0a77f4901a66793d51bf095eb98eb1d03998cf4c2c2021e29a4bb618e1539c733aa320ce6021a298d08601777c555439c58785086a8d35e1c779c43d68e8a0bd19107024a07f4a068aaacada3386186714161940220cb6a008c8b91842714e63ffc88952d0a20e9717200b9a289e6f91d2a3081e37d2403d12ecba16e5f75a44db011201f98452d4cb135a9595167d762445ad38ed54493ba5c43c8977acec321f077116b696222099dca63d40e065ef841367a0a8da9c08b6b5893f58cfb4e81ca66d7297a2774ade2bd76b80b018c102fe763bbcd89d6fb7cbab9b2f58742e71288314e4e46dd13c09ebe0bf2b23121af0660db1087803b55b3ac42dc7b19817dc869a203ec8b23d41710259662240a2e64bf40bbfcb2ae960376b6a80c236cbcfcb36b94e29c1056db3324869017cd8e661c273dc66e518a1367d7e4901d708fa14c5f4844de22c44708de2303a399554c407088970077d986d5eda2a335ee9073e858422ccbdc367d3b066a7f514645fa21787c72525fb75d3c329fb99527f896989689c031e14cef8a7c414063c15c0e3ad99415aff15234af3d692ffd947efc0dc5bdcf0d8b4cc0bcc2725a3cbe230c031e1016846f90b13bd892a5f8570971f1622a9320a587c8a32a3b53bcd4af443dca20ef10314a77c3c3edb6902f78ccf7e917584a6605807629ea9e36d865499df7c1dd537f93bdc8580b72de2baaa4f6f4b6774dd098c5bbb5366b1cf7ee71d566249d7f2e5297dc54902d64c6e03b30017628811c8c20b5c84e24edcdf8e22e04740913e26956354c95d497d479a7fb1a6fba8dc7e44bf255c161bb8bfb5bd211725c1fa6d89e777b53784dff198d56d9011f6492121207c4ddd49678425efbc77e5f202efaa77041531ca819fbc2115071978659b54a499842fedf22a24d02f0b287a711017e5abd1aa0bb600196123fc2da17d8d32851f91cb98bebf3f1f77ebc7dd662032ff92f023ee358f1ebff2ecfbb3233053858130adaec27b454bdc859eb9b68afc7424b9f67db8ca92108ce7923fbebb9c565a069c390e6cab5c291a9d4ac1e65ed1a86feed4a922a3c01c3dad940879f64ddfba997fb56ed4af4b431fcd6fd0e334ccfbb09a6f57f6ac58d9017a4847d45d0c2fbf2e86e55cd1eecff874ed48b7be39fa019451e62ef43eac86c9817e5423cf7e0c998c91d1beab2ca5852d6fbdee44f2ab61b9e74f4c29fcf2430aa771ad0f7669b5b2d5cc65679acb14d82aba77664fae2dc7de1869eb7b1c5ac6d5c61ad3be65a8634f9a6d3c5b465e76cfcf0ac6685bdba28e3d79aefae6f2cbca96d1da9142bf3baf027b265963726b197a1f2a28b50c75e13a7ae53a33e465f3a7c754db04374be2b6745a86be7a78dc713dd638a29ea1d66b53ef79f6f6d24a2329180f59ec7ff8ddc98f69aae67ef7be74154d992aead354d19e56ca884c9f6eca3b83c7a9ac63a86beb8515826cb6f17ee078ba9884463c0c619750cb5c96ee58d6588ca60bfd18937417b9ddd9bb71e0feb118482c0f4b6dbd8f89348f0273244147e73159317fae710cbba4b44d9970bb1c599b9a2329185bc453e43c3097d41fcf552bd6fff115adfc124f98ae5bb63eca6b143873e439ba04991fb5ddc84be7b5ad63da07f62a9c26f2c63597a4b671c8f96dff1e6c2d71ed2dabb787603c9157ddf9849fdf9535161b7ecd9b7ed732cc9fb9a21d72dfd033d796ef560eda04ce5c5b3bb43f4d82cd92d50cafd7e52cb077127074e23a1162f13fe498f98322eadd8c4a2fd5a49533cf3d453dc91f3b63c1d6c93ee6bb8d6723c9b5e56d304ee2d510ef6d3be697e79beee374bbbecffb5069f6583f7627919706c832d41bd776732f5d9ac05e92fdb56c26c02e09991faccf3d7b590686ae713dd59c58d758b3cc1df2e27deddc8553e75057b91beb59600c13cf186e2d4366d7f1dae079398d0daba1a73a27f721dce267b9fb3f539b8798dfd7b1080fbeb078945ef73e9c268d5e1e93663f09367b9dd67826f9292add4a0fa129932fb145564a14f929f3e126b6ccfcc9537a75dd246cadee6bf1d4ee74d8c4430a5d5b4d587ceadc317af7c4ce3ace043eaf26be24477e4a65dfa867a665e8879cf178b7e69ec56af85a0a1fec5105bacb6d6bbe105f790c3f74fdded763ce9b7a6d6ad538ccee431db39af4d351e92a8fe13499239fd5bbb92c570a427ea5bf5367436d6f8bebcc67ae338f7c65865d5b8e98ece3f37b4cd9f4f723d3b9cf11bfefd86ac27ce00f2d05cce8f1667dbc1df33bf9efc2d5fcf90cc11d2c7e11b47e76e101ba56a5b7a16b49fb4b561fe4cb81240d7adac5555f5635addf57fe2b29bf0c5df72f953f085d73cb7f09baeef57aca1e65ee5e5ef5ae94aed27b01bb96e4fe55afa71d00e9bdcf2f60d7cf447baaa65d49ca2776fd895d7f62d79fd8f52776fd895d7f62d79fd8f52776fd895d7f62d79fd8f52776fd47b0eb67cfb3ff9b0836de4c2bfd04c5f3b3bb70e54c9065a2d23551e5da33c9326b14d2aff4d2b59709b3c14db5ca1acf909fa2c833d1658df0f598dc93eb4cf295bdcb613a9280ad95467cb5b1ccd15383f2842b8e3244d433f414d83be4577a026c37751d2bf4ec91d45c4fe042cfbd589780b9ccfd788fa6cd653f7d2c391a3ed6a39542235769d0976bacd588cc19bf46eafab09ad35aa6d7a07a7bb9478e0a3ed357a38ab9e7e81b3fbb0f6f8d09f2d2d9c665b1a9348ea05971c291f9237a23cbde789efbe60e417359ed91d8b790765b969ff11fba93dc5550b9b2771c21b20c3d0d6cf587654494eb3686ffbc84e2dc2ef4a597ca919fcdf0cadedd3e4ada975bd36267c4d099a3db858efc6cb2f163bd7f4488d9a746d56ad41935c8ac1cf9e33692cce594956385c0569f803d470ff6686b9972e48f28cb4feea541f0ccae47ad0276907be98823d9c6e2a88f9de73a93aa465e797d944b5ba52b67f204cc11b9352d62196eee65b3dc3597b39533ccbf54cc072bb41ea4d04b11a9df50b46d3c7efc742905cea4b4582e427cb257c7b5256f6ef9db15cf1e15ee22f29ce788f7573f4519b0d5c81bcbdad4186ea7864e5cbb87dbf1b85d24677a5d16ef626ae80af773dca0d4262a7d0525eea31cf9c6793e5a9ff1aa3ca2e51441a74629c116bf2c6fe884edaf1c7debda6a726b6e89355ee54698b4744aa736ee91caf10cb5df0c9c7f827454b1387da0665fb3ed295090b452c27085c8d659bce1b7398b7ce5319c7449f6257c4d5fdb0737627302d86ae6994b89cd9af76af15d9d0647b979bdb1dae06f2f62b5d5635bbc8ab7e1249bb1da27ae33df7871d2e7f5160fa3af0bbd04f6b67e03f0ee591fabdb977dff902f2fd4c589ddafea70cd65ba729624b8c67f2e66e9f6977af965bf2728182f2baf3eef23b669afd5db79cd9ebf796aede1db54de7ae6b277bb186a96b9bd7dc52696fb5b7e66989fbcb5780f61afe155f8f97f00ff1f7e5cfefc1f000000ffff010000ffff85ba1470fa310000`)))