mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-31 11:17:01 -07:00 
			
		
		
		
	Compare commits
	
		
			41 Commits
		
	
	
		
			FluxEngine
			...
			kmedian
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | ce4cabde96 | ||
|  | ffbb6609c8 | ||
|  | 203a74713f | ||
|  | 5b66f803f3 | ||
|  | 33d14a5fbe | ||
|  | 5d27b6d9aa | ||
|  | 0d90dcee0f | ||
|  | c89f5b9649 | ||
|  | 59ed2a6793 | ||
|  | c5bc9a8cee | ||
|  | a03283ce64 | ||
|  | 347e4d59a3 | ||
|  | 984cdaeb03 | ||
|  | a1ed4a9171 | ||
|  | 6e56cc3b0a | ||
|  | 93caf8e549 | ||
|  | 3841942153 | ||
|  | 5706877b67 | ||
|  | d60900262b | ||
|  | 54ea34400b | ||
|  | db2ab8841a | ||
|  | adba93ae0a | ||
|  | 98587d04a7 | ||
|  | 0051b64648 | ||
|  | 603009ba15 | ||
|  | adb9809692 | ||
|  | 06eb10d2a0 | ||
|  | 2244299bd9 | ||
|  | 6ca06ecafb | ||
|  | 9a5958f80b | ||
|  | 2b53ac057c | ||
|  | 5deba8af41 | ||
|  | 3c54a663b8 | ||
|  | 1fd65452c4 | ||
|  | 30646ccb07 | ||
|  | 5be7249a30 | ||
|  | 067af18103 | ||
|  | 8dbd2a72a7 | ||
|  | c29e131a3b | ||
|  | a9e30c1e49 | ||
|  | 972c8c6b61 | 
| @@ -1,243 +1,243 @@ | ||||
| :400000000080002011000000990F0000990F0000064A08B5136843F020031360044B1A6803F53F5302331A6000F0D4FFE8460040FA46004010B5054C237833B9044B13B103 | ||||
| :400040000448AFF300800123237010BD6881FF1F0000000018380000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF00000000F1 | ||||
| :400080006C81FF1F18380000C880FF1F000000000A4A0B4B116801310B40002BBEBF03F1FF3363F03F030133136011685368994202BF024B01221A72704700BF8881FF1F6C | ||||
| :400000000080002011000000A10F0000A10F0000064A08B5136843F020031360044B1A6803F53F5302331A6000F0D8FFE8460040FA46004010B5054C237833B9044B13B1EF | ||||
| :400040000448AFF300800123237010BD6881FF1F0000000020380000084B10B51BB108490848AFF300800848036803B910BD074B002BFBD0BDE81040184700BF00000000E9 | ||||
| :400080006C81FF1F20380000C880FF1F000000000A4A0B4B116801310B40002BBEBF03F1FF3363F03F030133136011685368994202BF024B01221A72704700BF8881FF1F64 | ||||
| :4000C0003F0000800A4A0B4B516801310B40002BBEBF03F1FF3363F03F030133536051681368994202BF024B01221A72704700BF8881FF1F3F000080024B012200205A7293 | ||||
| :4001000002F00EB98881FF1F10B5C4B2204601F023F90128FAD110BD08B572B60F4B0F49DA680132DA601A690132C82A08BF00221A615A6918690132A72A08BF00224A6142 | ||||
| :400140005B69002B0CBF02230023002814BF184643F0010002F04CFE62B608BD8881FF1F38B50446C5B2284602F07CF8062002F099FA44F00200C0B202F074F8062002F065 | ||||
| :4001800091FA284602F06EF8BDE83840062002F073BA10B5642402F05FF830B90120FFF7DFFF013CF7D1204610BD012010BD70B5C4B2054620460E4601F0CEF8012805D09D | ||||
| :4001C000204601F0E7F92846FFF79EFF204601F0CBF8314605460246204601F087F9204601F0BAF80028FAD1284670BD38B5044D0024285D013402F005FA402CF9D138BDFD | ||||
| :40020000A081FF1F08B502F01FFC002002F028FC02F03AFC02F044FC80B208BD10B50446012002F037F8642002F026FAFFF7EAFF2080002002F02EF8642002F01DFAFFF70D | ||||
| :40024000E1FF608010BD08B502F02AFD002002F033FD02F045FD02F04FFD80B208BD10B50446FFF796FF322002F006FAFFF7EBFF20800020FFF774FF322002F0FDF9FFF759 | ||||
| :40028000E2FF608010BD0FB400B593B014AB53F8042B402102A8019302F0A6FE02A802F046F802F050F813B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF737 | ||||
| :4002C00023FF62782146BDE81040042001F09CB82C38000007B50023ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB000010B5074C94F8583043B10020EF | ||||
| :4003000001F0A4FF002002F037FD002384F8583010BD00BF8881FF1F38B5104D837895F85B2004469A4204D0FFF7E4FF002385F85E302368C5F859302279094B1A71A37855 | ||||
| :40034000002B14BF0220012002F016FDE07802F00DFD2079BDE8384002F044BD8881FF1FE181FF1F38B50D4C94F8585065B904F15900FFF7D1FF012001F068FF4FF47A7041 | ||||
| :4003800002F07AF984F85E50E3682366012384F85830BDE8384002F0ADB900BF8881FF1FF8B51E4C0646FFF7DDFF94F85E3003B15EB91B48FFF767FFFFF7EBFE012000235B | ||||
| :4003C00084F85E00636602F06DF93246616E1548FFF759FF114D0027636E9E4216D001F03BFF00B16F66636E9E4205DD0020FFF7B7FE6B6E013305E005DA0120FFF7B0FE4F | ||||
| :400400006B6E013B6B6602F075F9E5E7322002F033F9BDE8F8400448FFF735BF8881FF1F39380000403800005D3800002DE9F04F99B062B602F0C8F99949042002F0ECF93C | ||||
| :40044000984801F015FF984802F0B8FC974801F049FF02F099FB02F06BFA002002F08CFC01F064FF0221002000F02CFF904C012001F0A4F8002384F85B30FFF773FFFFF7BE | ||||
| :4001000002F012B98881FF1F10B5C4B2204601F027F90128FAD110BD08B572B60F4B0F49DA680132DA601A690132C82A08BF00221A615A6918690132A72A08BF00224A613A | ||||
| :400140005B69002B0CBF02230023002814BF184643F0010002F050FE62B608BD8881FF1F38B50446C5B2284602F080F8062002F09DFA44F00200C0B202F078F8062002F055 | ||||
| :4001800095FA284602F072F8BDE83840062002F077BA10B5642402F063F830B90120FFF7DFFF013CF7D1204610BD012010BD70B5C4B2054620460E4601F0D2F8012805D089 | ||||
| :4001C000204601F0EBF92846FFF79EFF204601F0CFF8314605460246204601F08BF9204601F0BEF80028FAD1284670BD38B5044D0024285D013402F009FA402CF9D138BDE9 | ||||
| :40020000A081FF1F08B502F023FC002002F02CFC02F03EFC02F048FC80B208BD10B50446012002F03BF8642002F02AFAFFF7EAFF2080002002F032F8642002F021FAFFF7ED | ||||
| :40024000E1FF608010BD08B502F02EFD002002F037FD02F049FD02F053FD80B208BD10B50446FFF796FF322002F00AFAFFF7EBFF20800020FFF774FF322002F001FAFFF740 | ||||
| :40028000E2FF608010BD0FB400B593B014AB53F8042B402102A8019302F0AAFE02A802F04AF802F054F813B05DF804EB04B0704710B5044601780648FFF7E5FF0420FFF72B | ||||
| :4002C00023FF62782146BDE81040042001F0A0B83438000007B50023ADF804308DF80600032301A88DF80530FFF7E2FF03B05DF804FB000010B5074C94F8583043B10020E3 | ||||
| :4003000001F0A8FF002002F03BFD002384F8583010BD00BF8881FF1F38B5104D837895F85B2004469A4204D0FFF7E4FF002385F85E302368C5F859302279094B1A71A3784D | ||||
| :40034000002B14BF0220012002F01AFDE07802F011FD2079BDE8384002F048BD8881FF1FE181FF1F38B50D4C94F8585065B904F15900FFF7D1FF012001F06CFF4FF47A7031 | ||||
| :4003800002F07EF984F85E50E3682366012384F85830BDE8384002F0B1B900BF8881FF1FF8B51E4C0646FFF7DDFF94F85E3003B15EB91B48FFF767FFFFF7EBFE0120002353 | ||||
| :4003C00084F85E00636602F071F93246616E1548FFF759FF114D0027636E9E4216D001F03FFF00B16F66636E9E4205DD0020FFF7B7FE6B6E013305E005DA0120FFF7B0FE47 | ||||
| :400400006B6E013B6B6602F079F9E5E7322002F037F9BDE8F8400448FFF735BF8881FF1F4138000048380000653800002DE9F04F99B062B602F0CCF99949042002F0F0F914 | ||||
| :40044000984801F019FF984802F0BCFC974801F04DFF02F09DFB02F06FFA002002F090FC01F068FF0221002000F030FF904C012001F0A8F8002384F85B30FFF773FFFFF79A | ||||
| :4004800088FE84F86800FFF735FF012384F85B30FFF768FFFFF77DFE84F86900FFF72AFF844B94F86800844994F869202546002A14BF0A461A46002808BF19467F48FFF7E3 | ||||
| :4004C000E2FE0321084602F0F5F8264602F012F994F8583043B12A6EEB689B1A41F28832934201D9FFF706FF00F024FF18B97448FFF7C9FE04E000F023FF0028F7D10BE0F5 | ||||
| :4005000000F018FF10B902F0F5F8F9E76D48FFF7BAFE032001F03EF8032000F01DFF0128D4D16948FFF7F8FE68490320FFF73FFE94F86A106648FFF7A6FE94F86A30023B2D | ||||
| :40054000142B00F2A783DFE813F01500A5031E00A5032400A5034600A5036C00A503CF00A503AA01A503DE02A503FD02A5030403A5031E0303238DF820308DF821300D233B | ||||
| :400580008DF82230FBE294F86C00FFF709FF514BF2E2FFF7E7FE00236372E068627A02F0FF0132B9EB681B1AB3F57A7FF6DD0B4608E03BB100227272F168627A12B9EB68D3 | ||||
| :4005C0005B1AFAE707228DF8202004228DF82120ADF82230D3E20220FFF796FD4FF000080DF1200A02F086F84FF480790027C9EB0803DA1907F80A200137402FF9D10220C4 | ||||
| :40060000FFF782FD3A465146022000F0FDFEB9F10109EBD108F10108B8F1400FE2D12E4B38E04FF0010A4FF000080DF1200B02F061F84FF0000959460120FFF7B8FD08EBC8 | ||||
| :4004C000E2FE0321084602F0F9F8264602F016F994F8583043B12A6EEB689B1A41F28832934201D9FFF706FF00F028FF18B97448FFF7C9FE04E000F027FF0028F7D10BE0E5 | ||||
| :4005000000F01CFF10B902F0F9F8F9E76D48FFF7BAFE032001F042F8032000F021FF0128D4D16948FFF7F8FE68490320FFF73FFE94F86A106648FFF7A6FE94F86A30023B1D | ||||
| :40054000142B00F2AB83DFE813F01500A9031E00A9032400A9034600A9036C00A903CF00A903AA01A903E202A9030103A9030803A903220303238DF820308DF821300E23FD | ||||
| :400580008DF82230FFE294F86C00FFF709FF514BF6E2FFF7E7FE00236372E068627A02F0FF0132B9EB681B1AB3F57A7FF6DD0B4608E03BB100227272F168627A12B9EB68CB | ||||
| :4005C0005B1AFAE707228DF8202004228DF82120ADF82230D7E20220FFF796FD4FF000080DF1200A02F08AF84FF480790027C9EB0803DA1907F80A200137402FF9D10220BC | ||||
| :40060000FFF782FD3A465146022000F001FFB9F10109EBD108F10108B8F1400FE2D12E4B38E04FF0010A4FF000080DF1200B02F065F84FF0000959460120FFF7B8FD08EBBF | ||||
| :40064000090300270493049B1BF807203B44DBB2934209D08DE80C0041463B464A461F48FFF711FE4FF0000A0137402FEBD109F10109B9F5807FDED108F10108B8F1400F92 | ||||
| :40068000D5D151461648FFF7FEFDBAF1000F00F00E81144B1B8807A8ADF81C3070E200BF19010000F900000091000000C50000008881FF1F6F3800006B380000723800003E | ||||
| :4006C0008A3800009D380000E181FF1FF281FF1FA73800001C3800001E380000B6380000D23800002038000094F86C0001F0D2FD606EFFF755FE02F0E3FBB04BDFF8D882AE | ||||
| :400700001A78002702F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0D1FB0220FFF7EEFC012141F6FF734FF48042084602F024FB84F8AA0005 | ||||
| :4007400001F046FF08F807000137402FF8D1DFF88CA200270AF199091FFA89F80137402F14BF3A4600221AF8010F22440623127E402101F061FF424646F248519AF800006F | ||||
| :4007800001F06CFF08F14008402F1FFA88F8E5D196F86D3033B100237372637A002BFCD00023737200234FF0FF32236062602372236894F8AA002344197E01F0C1FE94F883 | ||||
| :4007C000AA0001F07FFE012194F8AA0001F052FE2368002BFCD0002398467360D6F80CA0012701F087FFE368B4F86E20CAEB030393420DD367B1042195F8AA0001F0ACFED5 | ||||
| :4008000094F8AA0001F0B8FE0028F9D107463072237AFBB96A682B689A4202D1002FE0D118E00220FFF770FC6968402209EB8111022000F0E9FD6A68614B01321340002B59 | ||||
| :40084000BEBF03F1FF3363F03F03013308F101086360C6E70220277AFFF756FC00221146022000F0D1FDFFB20220FFF74DFCFFF7BDFC37B15348FFF706FD0220FFF72AFDBA | ||||
| :4008800006E0514B08A81B88ADF82030FFF710FD627A4146237A4D48FFF7F5FCFDE14C48FFF7F1FCD4F86E7017F03F0701D00320F1E1012001F0F4FC95F86C0001F0EAFC0B | ||||
| :4008C00002F0FEFA434BDFF810811A7842F004021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0EDFA686EFFF756FD01214FF4804341F6FF72084641 | ||||
| :4009000001F0D4FC85F8AA0001F062FE08F807000137402FF8D1DFF8C490002709F199031FFA83F804930137402F14BF3A46002219F8010F22440523127E402101F07CFECD | ||||
| :40094000414646F24C4299F8000001F087FE08F14008402F1FFA88F8E5D100274FF0FF33376098467360BB46BA463B46D6F86E9037724FEA99192168114A01310A40002AD8 | ||||
| :40098000BCBF02F1FF3262F03F026068B8BF013282426BD02BB1227A002A76D16A7A002A73D12068049A059302EB8010BAF1000F16D040223F2102F0E3FA1CE098650040B4 | ||||
| :4009C0003F000080DC38000022380000F6380000093900009C640040A081FF1F9F81FF1F014601370120FFF7E2FBC7EB0903D3F1000A4AEB030A2168AB4A01310A40002A38 | ||||
| :400A0000BEBF02F1FF3262F03F02013222606268059B01322AD12A683F2A27D14FF00008C5F8048001F070FC85F808806B6895F8AA002B44197E01F083FD95F8AA0001F0AF | ||||
| :400A400041FD012195F8AA0001F014FD85F80980637A002BFCD04FF00008012086F8098001F05EFC404601F01BFC00E023B1237A5BB96B7A4BB90123626842453FF47BAF9B | ||||
| :400A80000BF1010BD5F8048075E701F043FC012001F006FC002001F043FC042194F8AA0001F05AFD94F8AA0001F066FD0028F9D196F8AA0001F0F4FC737A327A0293012363 | ||||
| :400AC00003920193CDF800A05B463A4649467748FFF7D9FBBAF1000F08D0FFF787FB237A63B17348FFF7CFFB0220D4E0B945F4D070490120FFF75BFB0137F7E76E48FFF779 | ||||
| :400B0000C2FB6E4B38E094F86C0001F0C3FB606EFFF746FC6A48FFF7B6FB00236372637A002BFCD0012001F0FBFB00237372637A002BFCD0002001F0F3FB6248FFF7A3FB34 | ||||
| :400B4000614B19E0002084F85E00FFF729FC5F4B12E094F8683023B195F869200AB985F86C2094F869201AB113B9012385F86C305748FFF7D1FB574B1B88ADF8203008A811 | ||||
| :400B8000FFF796FB89E0FFF7B5FB02F07BF8002002F01EF82A2701F049FF002001F0ECFE3A46002108A802F0EBF917238DF820308DF8217001F09EFD002001F047FB002042 | ||||
| :400BC00002F0DAF8C82001F057FD0DF12200FFF725FB0DF13600FFF742FB01F08BFD012002F0CAF8322001F047FD0DF12600FFF715FB0DF13A00FFF732FB012001F026FBDA | ||||
| :400C00004FF4967001F038FD01F074FD0DF12E00FFF704FB0DF14200FFF721FB002001F015FB4FF4967001F027FD01F063FD022002F0A2F8322001F01FFD0DEB0700FFF79E | ||||
| :400C4000EDFA0DF13E00FFF70AFB012001F0FEFA4FF4967001F010FD01F04CFD0DF13200FFF7DCFA0DF14600FFF7F9FA002001F0EDFA4FF4967001F0FFFC01F03BFD00202C | ||||
| :400C800002F07AF8002384F85E3001F07DFF01F04FFE74E70120FFF71DFB032000F07AFC0D48FFF7F0FA11E43F00008013390000433900003892FF1F4D390000243800006A | ||||
| :400CC00055390000633900002638000028380000F281FF1F2A380000703900002DE9F04172B6884B61221A70A3F5F06301221A801924854A9C7092E803008033062283F88E | ||||
| :400D0000002283E80300522203F580731A707F4B7F4A1B787F4EDBB2137040F618027E4B00251A8041F2512223F8022C33784FF4F07003F0010343EA450502F0B9F8013CD4 | ||||
| :400D400005F003052ED0032DF0D1744B4FF480721A8007221A70724A002548211570917002221D705D7103F8032C0422DA716D4A6D4C13786D4E43F00103137012F8013CA5 | ||||
| :400D8000062743F0030302F8013C2378012243F0800323705B4B1A70654A137843F02003137000E0FEE707FB056300219A881868013502F0E5F8072DF5D15E485E4E0025E4 | ||||
| :400DC00050F8041F05F1105303F1480221F0FF074933C9B20B4452005B0002329A4206D012F802EC12F801CC0EF807C0F5E7B0420D44E5D1514A0023136093601361936104 | ||||
| :400E00004F4B504F1A68504BDFF888811A604F4B1A684F4B1A604F4A137843F002031370137C43F0020313742378A2F5863243F040032370413A137843F010031370464A53 | ||||
| :400E4000464B07CA03C31A80454A2833106843F8250C127903F8212C424A07CA03C31A80414AE83B07CA03C31A80404A083307CA03C31A803E4A3F4BA2F5616203CBC2F889 | ||||
| :400E8000100EC2F8141E1378042043F008031370394B02F5AA521B783D78DBB298F80060EDB203F007010C321B091170F6B2537045F003033B7046F0030388F800302F4B48 | ||||
| :400EC00048221A702E4A402313702E49937013729372082382F81F3220220A7048710A72294A0A20137001F0DDFB284B88F8006044223D70264D1A7094E80F0007C52B8067 | ||||
| :400F0000BDE8F08100480040940A00480F010049A146004025420040224200400440004006400040A2430040A043004075390000E8460040FCFFFF478C0000480076004029 | ||||
| :400F40009C0A0048F846004020760040A00A00482876004003500140540A0048C0510040600A0048680A0048740A0048800A0048325100408C0A0048CF0100491D51004068 | ||||
| :400F800001590040235B0040585B004076580040B0430040F946004008B501F0C5FF03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC086005E001F0B4FF34 | ||||
| :400FC0000C2303604FF0FF33184608BDCC80FF1F8893FF1F80B51148114B0025C0B1A3F1100192C922460439161BB74204D051F8046F42F8046BF7E7114653F8046C8C1A0A | ||||
| :40100000A64202D041F8045BF9E701381033E5E701F090FFFFF70AFAFEE700BF01000000443B0000124A134B10B51A60124A134C1368134843F4007313600023032B98BF49 | ||||
| :4010400054F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF73BFEBDE8104001F0EDB900BF0004FA050CED00E014ED00E0000000007C | ||||
| :401080000080FF1F990F0000BC760040C080FF1F08ED00E0F8B501F013FF4B4A01271378022643F001031370137C484C43F001031374474B02F5E3521F700B3203F8946C05 | ||||
| :4010C0001378054603F07F031370002001F0EAFA2378404A03F0F90323701378384603F0DF03137023783B43237001F0DBFA282001F0D8FA384B30461A7802F07F021A7020 | ||||
| :401100001A7802F0BF021A7023783343237001F0C9FA2378314A43F0040323700023137053702F4AFF2199540133092BFBD1284601F0CAFE0721172001F0FCFA294917206C | ||||
| :4011400001F0EAFA0721182001F0F4FA2649182001F0E2FA0721152001F0ECFA2349152001F0DAFA0721052001F0E4FA2049052001F0D2FA0721062001F0DCFA1D49062045 | ||||
| :4011800001F0CAFA0721084601F0D4FA1A49072001F0C2FA0721082001F0CCFA1749082001F0BAFA0021162001F0C4FA1449162001F0B2FA07210C2001F0BCFABDE8F840CC | ||||
| :4011C00010490C2001F0A8BAA5430040944300409D60004012600040F851004084600040AD92FF1F631A00009D180000611A000095190000C1190000F1190000291A00005D | ||||
| :40120000691A0000DD1A0000214B224A10B5187000231370204A40201370204A0F2413701F4A13701F4A13701F4A13701F4A13701F4B4FF400021A604FF080721A604FF435 | ||||
| :4012400000121A6020221A601860802018604FF480701860174804704FF480001860164B1A70933B19B91A7802F0FE0202E01A7842F001021A70114B03221A70802203F8F3 | ||||
| :40128000202C012001F014FE0D4B04221A7010BDC892FF1FCE92FF1FCC92FF1FCD92FF1FC992FF1FB892FF1FCB92FF1F4093FF1F00E100E09E6000409C60004028600040AA | ||||
| :4012C0001260004070B5074C054623780E461BB9FFF7E0FE0123237031462846BDE87040FFF792BF7892FF1F0A4A002313700A4A13700A4A13700A4A13700A4A13700A4AD8 | ||||
| :4013000013700A4A13700A4B03221A70802203F8202C7047CE92FF1FCC92FF1FCD92FF1FC992FF1FB892FF1FCB92FF1F4093FF1F28600040014B1878704700BFCD92FF1F54 | ||||
| :40134000044B1A7802F0FF001AB118780022C0B21A707047CC92FF1F024A0C2303FB002040787047D492FF1F431E072B0CD8074A064B00010344805C5B7800F00F0043EA27 | ||||
| :401380000020023880B2704700207047FC5F00401A4A38B50C2303FB00231B79090C13F0800F00F1FF35044619BF8AB24FF480438BB24FF48042032D18D8DFE805F00207EC | ||||
| :4013C0000C110021084601F01BF80DE00021084600F0FAFF08E00021084600F0D9FF03E00021084600F0B8FF054B1855EDB2072D03D801F0EDF8034B185538BDD492FF1F8B | ||||
| :40140000A492FF1FAD92FF1F431E072B2DE9F0470446894615465CD82F4F0C2202FB0072D388DFF8B8A09BB2C3F500739D424FF00C0303FB007388BFD588DB7884BFC5F5C4 | ||||
| :401440000075ADB2254A43EA15230601B354B244EBB28AF80130224B1A5C9846FF2A01D1FFF796FF0C2303FB047200215170B9F1000F28D03DB31B4F385D01F011F81123D6 | ||||
| :401480002946FE2218F8040001F0D6F806F5C04278321FFA89F118F8040001F0DFF8124D18F80410385D01F04BF80121385D00F0E1FF735D43F002037355735D03F0FD034E | ||||
| :4014C0007355BDE8F08703FB04746379DBB28AF80230BDE8F08700BFD492FF1FFC5F0040AD92FF1FA492FF1F706000402DE9F047044615468846002940D0431E072B3FD817 | ||||
| :40150000FFF732FFA84203D22046FFF72DFF05461D4E335DFF2B03D141462046FFF738FFDFF868A027011AF8040000F0B9FF1223FE222946305D01F07FF807F5C0411FFA4B | ||||
| :4015400088F27831305D01F089F8DFF84490315D1AF8040000F0F4FF01211AF8040000F089FF17F8093043F0020307F8093017F8093003F0FD0307F8093002E00D4600E027 | ||||
| :4015800000252846BDE8F087AD92FF1FA492FF1F70600040431E072B0AD8064A0C2303FB002300225A705A79034BD2B200011A54704700BFD492FF1FFE5F0040431E072B7C | ||||
| :4015C0009FBF024B000108221A547047FE5F004030B51A4A1A491B4D0878138803449BB21380194A00231488D8B2A4B27CB1082B0CD050680078C0B2E854506801330130C4 | ||||
| :4016000050601088013880B21080ECE718460B780E4C082B0E4A00D040B10E4D2B7883F080032B700F232370022301E0022323701370094B1870087030BD00BF4493FF1F83 | ||||
| :401640004093FF1F00600040BC92FF1FB992FF1FCE92FF1FCA92FF1F4193FF1F074B02221A70074B80221A70064B0F221A70064A00231370054A012013707047CE92FF1F72 | ||||
| :40168000CA92FF1FB992FF1F4093FF1F4193FF1F30B5164B16491B780A8803F00F03023BDBB21A4492B20A80124C134A0020118889B279B173B15568215C013BC9B2297018 | ||||
| :4016C0005168DBB20131516011880130013989B21180ECE7094A1370094A137883F080031370084B0B221A7030BD00BF296000404493FF1F00600040BC92FF1F4193FF1F7F | ||||
| :40170000CA92FF1FB992FF1F064A06231370064A01201370054B80221A70054B00221A70704700BFCE92FF1FB992FF1FCA92FF1F4193FF1F054B9A683AB19A680449107089 | ||||
| :401740009A680988518000229A607047BC92FF1F4493FF1F08B5124B1A78D2B21A701B78DBB21A0602D50F4A137008BD0220FFF7E1FF0D4B1B7803F06003202B05D0402B9B | ||||
| :4017800006D043B900F012FC04E001F0A1FB01E000F046FD10B9034B03221A7008BD00BF28600040B992FF1F0060004008B5084A084B0120197813880B449BB21380064B8A | ||||
| :4017C00000221A70FFF7B6FF044B03221A7008BD4493FF1F4093FF1FCE92FF1FB992FF1F08B50C4B1B78DBB2042B07D0062B09D0022B0DD1BDE80840FFF7D8BFBDE808404C | ||||
| :40180000FFF746BF0320FFF795FF034B03221A7008BD00BFCE92FF1FB992FF1F08B5054B002201201A70FFF785FF034B03221A7008BD00BFCE92FF1FB992FF1F08B50A4BCA | ||||
| :401840001A7832B11A78094942F080020A7000221A70074B002201201A70FFF76BFF054B03221A7008BD00BFB892FF1F08600040CE92FF1FB992FF1F074B1B78DBB2042B9B | ||||
| :4018800005D0062B05D0022B05D1FFF7A1BEFFF7C5BFFFF7D3BF7047CE92FF1F38B51D4C2378DBB2DD0634D518060AD503F00F03012B2ED1FFF74EFF174B1B78190609D5F2 | ||||
| :4018C00038BD5A0602D5FFF7D7FF03E09D0620D5FFF786FF23781B061BD4104B1A78104B1B7813430F4A13701278934211D10A4A0849154613782078DBB2000605D41378E7 | ||||
| :40190000DBB20B700B7803F00F0328788342F1D138BD38BD28600040B992FF1FCA92FF1F4193FF1F29600040054A00231380054A916819B191680B7092685380704700BFD2 | ||||
| :401940004493FF1FBC92FF1F0E4808B503889BB213B9FFF783FE13E00B4B02221A700B4B00221A70FFF7E0FF094AD1799379028843EA012392B2934238BF0380FFF728FED7 | ||||
| :40198000012008BDBC92FF1FCE92FF1FCA92FF1F00600040084B01221A700F3B9B7C074B1A7B02F00302012A1EBFDA7B82F08002DA7301225A7370470B600040D492FF1F8A | ||||
| :4019C000094B02221A700F3B93F82230074B1A7E02F00302012A1EBFDA7E82F08002DA7601225A76704700BF0B600040D492FF1F0B4B04221A700F3B93F83230094B93F885 | ||||
| :401A0000242002F00302012A1EBF93F8272082F0800283F82720012283F82520704700BF0B600040D492FF1F0B4B08221A700F3B93F84230094B93F8302002F00302012AB1 | ||||
| :401A40001EBF93F8332082F0800283F83320012283F83120704700BF0B600040D492FF1F7047FFF741BC0000F0B5184B184E19780C27C9B201234FF0000C31B3CA0720D5E5 | ||||
| :401A8000144A4FEA031E7244947850782040C5070DD507FB03652C79240608D5147804F0FE0414706D790C4CEDB204F80E50840706D507FB036425792D0658BF84F801C08F | ||||
| :401AC00090700133DBB24908D7E7F0BD9F600040D492FF1F70600040FE5F004000F0ACBC70B50446184B88B003AA03F11006154618685968083303C5B3422A46F7D11B7881 | ||||
| :401B00002B70FCB12223237001AD03232846637000F08AFE002220461146AB5C08AC04EB131414F8144C03F00F03847008AC234413F8143C0132082AC1700371417100F1C0 | ||||
| :401B40000400EAD108B070BD9F3900002DE9F0431C4D01222E460C201F274FF0800E4FF0080C194B00FB02581401234418705F70164998F805902144B9F1000F07D098F879 | ||||
| :401B8000044024064CBF887081F802C001E081F802E000FB0261CC880132E4B29C71CC88092AC4F30724DC71CC88E4B21C71C988C1F307215971D4D1054BFF221A70BDE84C | ||||
| :401BC000F08300BFD492FF1F70600040FC5F00400A600040064B074A1B7802EBC30253681A7C824286BF03EBC003586900207047C892FF1F003A00002DE9F84F424B1A7822 | ||||
| :401C0000002A7ED01878414D0138C0B2FFF7E2FFA8463F4AC3681478007ADFF800C1E4B203EBC0000C2600274FF0010E834268D01A78A24263D11CF80420597891425ED1AF | ||||
| :401C40009A7893F8039002F07F0206FB02FA05EB0A01CF7093F802B009F0030981F804B093F803B005F80AB0B3F804A0A1F808A093F902A0BAF1000F0BDAB9F1010F0CBF44 | ||||
| :401C80004FF007094FF00D0981F8059081F801E009E0B9F1010F0CBF4FF005094FF0090981F805904F704FEA02191A4906FB0282494481F802E0B2F808A0CAF3072A81F862 | ||||
| :401CC00000A0B2F808A05FFA8AFA81F801A0B2F806A011495FFA8AFA494481F806A0B2F80690C9F3072981F80790B2F806905FFA89F981F80490D288C2F307224A71083336 | ||||
| :401D000094E7BDE8F88F00BFCD92FF1FD492FF1FC992FF1FFC5F004070600040BA92FF1F08B5064B18780138C0B2FFF753FF20B143681B7900EBC300406908BDCD92FF1F74 | ||||
| :401D400000212DE9F84F0B464E4E0C2707FB01F401313219092933554FF000059370494CD3701381937253705371EFD118B1464B1D70464B1D70464B1A78002A7FD0187867 | ||||
| :401D800001250138C0B2FFF725FFA8464368DFF8F8E0DB790C2713F0400F3E4B4FF0000C1A7814BF42F0010202F0FE021A70027AD20007FB0541C36803EB02094B4531D0E2 | ||||
| :401DC00093F802A00AF07F06AE4229D10E89B3F804B0B6B25E4538BFA1F808B01E7893F801B01EF80660B3451AD181F804A0DE780E7093F902A0DE78BAF1000F06F00306A5 | ||||
| :401E000007DA012E0CBF07260D264E7181F8018006E0012E0CBF052609264E7181F801C00833CBE70135092DC3D1C1680A328B1C0A440C200833934209D013F8081C13F8E5 | ||||
| :401E40000A5C01F07F0100FB01418D72F2E7FFF767FF114B0121186000230C2000FB0142D3801289013113449BB203F00102134409299BB2F2D1BDE8F84FFFF767BEBDE898 | ||||
| :401E8000F88F00BFD492FF1FBA92FF1F4293FF1FCD92FF1FCB92FF1FD092FF1F114B1B7903F07F035A1E072A19D80F490C2202FB031291781B0141F0010191700021D17031 | ||||
| :401EC000517841F002015170127912F0800F074A1A4414BF8D2389239370FFF715BC0020704700BF00600040D492FF1FFC5F004030B4194B1A7902F07F02531E072B27D81B | ||||
| :401F0000164B0C2404FB02339978154D01F0FE0199700021D97029461201505D114400F07F0050555A7802F0FD025A701A795B78120605D5012B01D18C7006E00D2303E096 | ||||
| :401F4000012B0CBF082309238B7030BCFFF7DCBB002030BC704700BF00600040D492FF1FFC5F004010B50D4B0D4C21791878C9B20138C0B2FFF72EFE43681B798B4201D297 | ||||
| :401F8000012909D8074A0848535CDBB24354A3780120DBB2535410BD002010BDCD92FF1F00600040BA92FF1F4293FF1F38B58A4A8A4C13780021DBB221801806517840F175 | ||||
| :401FC0008D800A2900F20581DFE811F05D00030103010301030103010B0003017E0003018200D3787C49012B09D17D4B1A787D4B03EBC2035B685B686360122310E0CB7841 | ||||
| :40200000022B12D18878FFF7E5FD002800F0E180436863606368DA7863689B7843EA02232380BDE83840FFF78FBCCB78032B26D16D4B00228878D5B2854209D3664A91785E | ||||
| :402040006A4AEE2908BF1346634A917881B106E0187801320028F1D018780344EAE764499278097C914203D16248FFF739FD614B1A78002A00F0AD801A78228018E0BDE844 | ||||
| :40208000384000F025BF13F0030313D0022B40F0A0802380504B0C211B7903F07F02564B01FB02339A78554BD2B21A7000225A706360B6E702222280514A11784F4AC9B21C | ||||
| :4020C000117053706260ACE7012323804D4BEFE70123238013794C4A1344E9E701390A2977D8DFE801F037764F76067676760A7620009378454ADBB25AE0937803F0FF01B5 | ||||
| :4021000053B9404B1A7891425FD01970404B01201870FFF715FE58E0481EC0B2FFF75AFD0028EED155E0FFF71DFF002851D02A4A384913791279DBB2D2B20A70364A324948 | ||||
| :40214000D25CCB5C9A4240D0314B01221A70FFF753FD3AE003F00303012B2BD009D3022B37D11D4B9B78002B33D1BDE83840FFF7BFBE194B9B78012B2BD1214A137803F0A2 | ||||
| :40218000FD0315E003F00303012B13D008D3022B1FD1114B9B78E3B9BDE83840FFF77EBE0D4B9B78012B14D1154A137843F0020313700AE0084B1A795AB998781B791749C8 | ||||
| :4021C000DBB2CA5C22EA0002CA54BDE83840FFF79BBA002038BD00BF00600040BC92FF1FC892FF1F003A0000643A0000EC390000D73A00006093FF1FD492FF1F7992FF1F74 | ||||
| :40220000CB92FF1FCD92FF1FBA92FF1FB892FF1FCC92FF1FC992FF1F4293FF1FCF92FF1F074B1A78120609D55B78012B06D1054B054A5A6012781A80FFF786BB0020704732 | ||||
| :4022400000600040BC92FF1FC4390000014B1870704700BF77650040014B1878704700BF67650040014B1870704700BF7F640040064A0123136002F688321268E02110649C | ||||
| :40228000034A1170A2F540721360704780E100E000E400E0014B1870704700BF78650040014B1870704700BF7D64004073B515461E460B4C05230022019200920A460146C2 | ||||
| :4022C0001846237000F064F932462946207800F01FF90221207800F009F9207802B070BDD080FF1F064A0423136002F688321268E0219064034A1170A2F2023213607047BC | ||||
| :4023000080E100E002E400E0014B04221A60704700E100E0014B04221A60704780E100E0014B1870704700BF78640040704738B505460078012428B100F062FD285D01347A | ||||
| :40234000E4B2F8E738BD08B50D2000F059FDBDE808400A2000F054BDF7B516461F460B4C00230325019300930A4601462846257000F00EF93A463146207800F0C9F8022181 | ||||
| :40238000207800F0B3F8207803B0F0BDE080FF1FF7B516461F460B4C00230225019300930A4601462846257000F0F2F83A463146207800F0ADF82946207800F097F8207889 | ||||
| :4023C00003B0F0BDE180FF1FF7B516461F460B4C00230125019300930A4601462846257000F0D6F83A463146207800F091F80221207800F07BF8207803B0F0BDE280FF1FD4 | ||||
| :4024000073B515461E460B4C0023019300930A4601461846237000F0BBF832462946207800F076F80221207800F060F8207802B070BD00BFE380FF1F024B1878C0F3801032 | ||||
| :40244000704700BF8F450040074A7F23802113705170064A013BDBB202F80839002BF9D1034A1370704700BFE480FF1FF87B00400078004017280FD8084B0001C25C11B124 | ||||
| :4024800042F0200201E002F0DF02C254C25C42F00102C25400207047012070471070004017280BD8064B0001C25C02F0FE02C254C25C02F0DF02C2540020704701207047D6 | ||||
| :4024C0001070004017280DD8074900010B4603441A7942F004021A71435C43F00103435400207047012070471070004017280BD8064A0001835C490003F0F10301F00E015B | ||||
| :402500001943815400207047012070471070004041F6FF73994208BF4FF400519A4208BF4FF4005217289FBFC00000F1804000F5EC4081809ABFC280002001207047000021 | ||||
| :4025400017289FBF034B00011954002088BF0120704700BF1970004017289FBF054B00011A5C01F007019DBF1143195400200120704700BF1470004017289FBF034B00015A | ||||
| :40258000185C00F0070088BFFF20704714700040172810B51AD8C00001F07F0100F1804441EAC21204F5EC44D2B222709DF8082003F00F0343EA0213DBB263709DF80C3080 | ||||
| :4025C000002003F00F03A370E07010BD012010BD10B500F075FC0A4A5378182B0AD91478013B5370E30003F1804303F5F0431B78137000E0FF2400F067FC204610BD00BF7F | ||||
| :40260000E480FF1F030610B5044611D400F058FC084AE300117803F1804303F5F04319705378147001335370BDE8104000F04CBC10BD00BFE480FF1F30B504060CD411F499 | ||||
| :40264000704509D1C40004F1804404F5F0442180A270E370284630BD012030BD03065FBFC00000F1804000F5F04081805ABFC280002001207047000038B50446084DB4F56C | ||||
| :40268000004F05D9286800F013FCA4F50044F6E7034B58686043BDE8384000F009BC00BFEC80FF1F024B1B7A584300F001BC00BFEC80FF1F0E4B00F003001A78490102F04B | ||||
| :4026C000FC02104318701A7801F0600142F080021A701A7802F07F021A701A7802F09F020A431A701A7842F010021A70704700BF83430040014B01221A70704784430040C1 | ||||
| :40270000044B00F00F021B6853F8220043F82210704700BF08ED00E0054A00F01F00126800F1100352F8230042F82310704700BF08ED00E000F01F0000F16040490100F5C1 | ||||
| :402740006440C9B2017070470F4B10B50F4900240F205C609C60DC601C615C61FFF7D0FF0B4A136843F0040313600A4B4FF47A72DB68B3FBF2F3084A1360084B4FF40042E1 | ||||
| :402780001C60C3F8E82010BD7C92FF1FF527000010E000E0EC80FF1F14E000E018E000E0024A136843F002031360704710E000E008B5FFF7F5FF034A136843F001031360AD | ||||
| :4027C00008BD00BF10E000E010B5054CA3691BB9FFF7BAFF0123A361BDE81040FFF7E8BF7C92FF1F024B1868C0F30040704700BF10E000E038B5FFF7F5FF012808D1054DC9 | ||||
| :40280000002455F8243003B198470134052CF8D138BD00BF8092FF1F024B03EB80035868596070477C92FF1F134B144A1B78DBB20360127843EA0223114A0360127843EA83 | ||||
| :402840000243104A0360127843EA026303600E4B0E4A1B78DBB24360127843EA02230C4A4360127843EA02430A4A4360127843EA02634360704700BF0301004904010049CB | ||||
| :40288000EC460040020100490101004900010049050100490601004910B500F011FB204A044613780A2043F002031370137C43F00203137412F80A3C43F0010302F80A3C2C | ||||
| :4028C000937943F00103937102F5AB52137843F003031370134B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222183BFA | ||||
| :402900001A70094A137843F008031370FFF7CAFE064B10222046BDE810401A6000F0D4BAAB4300400E5900402F5B004080E200E008B500F0C5FA0F4A137803F0FE03137032 | ||||
| :40294000A2F5AA521D3A137803F0FD031370137C03F0FD03137412F80A3C03F0FE0302F80A3C937903F0FE039371BDE8084000F0ABBA00BF08590040044A137803F03F032B | ||||
| :4029800043EA8010C0B21070704700BF08590040082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A80A9 | ||||
| :4029C00042F210734B4341F2883103F6C41393FBF1F305490B60054B1A8070470A590040B03900004A93FF1F4C93FF1F5093FF1F08B5102000F0A6F907210420FFF79AFE2F | ||||
| :402A000007490420FFF788FE064A0C20137843F006031370FFF7BCFF034B00221A8008BDE92A0000095900404893FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040B0 | ||||
| :402A4000FFF72ABF9892FF1F044B1A7802F0FB021A701A7842F001021A7070470859004010B5084B1C7814F0010403D10028F9D0002404E02046FFF715FE024B1B782046F5 | ||||
| :402A800010BD00BF09590040034A044B1B881088181A00B2704700BF5093FF1FA25B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107386 | ||||
| :402AC00000B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270474A93FF1F4C93FF1F4893FF1F7047000010B500F0E7F9214A044613780A2043F001031370B1 | ||||
| :402B0000137C43F00103137412F80A3C43F0020302F80A3C937943F00203937102F5AA521832137843F003031370144B18221A7013F8012C42F0400203F8012C13F8012C85 | ||||
| :402B400002F0FC0203F8012CCE2203F8062CA3F597530222123B1A70094A137843F008031370FFF79FFD074B08222046BDE810401A6000F0A9B900BFAB4300400659004043 | ||||
| :402B8000275B004080E200E008B500F099F90F4A137803F0FE031370A2F5AA52153A137803F0FE031370137C03F0FE03137412F80A3C03F0FD0302F80A3C937903F0FD0307 | ||||
| :402BC0009371BDE8084000F07FB900BF00590040044A137803F03F0343EA8010C0B21070704700BF00590040082804D00A280CBF8223C22300E0422308380E4AC0B2042892 | ||||
| :402C0000137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A80704702590040BA3900005693FF1F90 | ||||
| :402C40005C93FF1F5493FF1F08B5102000F084F807210320FFF76EFD07490320FFF75CFD064A0C20137843F006031370FFF7BCFF034B00221A8008BD412D0000015900402D | ||||
| :402C80005893FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF728BF9992FF1F044B1A7802F0FB021A701A7842F001021A7070470059004010B5084B1C7814F038 | ||||
| :402CC000010403D10028F9D0002404E02046FFF7E9FC024B1B78204610BD00BF01590040034A044B1B881088181A00B2704700BF5493FF1FA05B00400E4A13881BB223B150 | ||||
| :402D000011880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270475693FF1F5C93FF1F5893FF1F53 | ||||
| :402D400070470000034A00F0F800137803431370704700BF02410040034A00F0F800137803431370704700BF06410040014B1870704700BF7B650040014B1870704700BFE0 | ||||
| :402D80007665004073B515461E460B4C04230022019200920A46014618462370FFF7F8FB324629462078FFF7B3FB02212078FFF79DFB207802B070BDFC80FF1F074A0223E8 | ||||
| :402DC000136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E0014B1870704700BF79640040014B1870704700BF7A650040000000008F | ||||
| :402E0000FEB5494652465B460EB40746244909688A46244A12682448022100F071F8030020480068C018204900F06AF8143883460121C9430C460125002600F041F8814653 | ||||
| :402E400051460B7823400B705846013000F030F83800F04028400B78234003430B70584600F026F80136072EF2D9002001300138013001200B78234003430B7058460430C4 | ||||
| :402E800000F016F8484600F01FF800BF00BF00BF0EBC894692469B46FEBD00BFAFF30080D480FF1FF880FF1F00C20100000000000230800803D000BF01380046FCD170473A | ||||
| :402EC000EFF3108072B6704780F31088704700BF094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E013790020704700600040D492FF1FF3 | ||||
| :402F0000002902D0B0FBF1F0704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB11217047704700BF014B1868704700BF6081FF1F0E4B70B51E460E4C0025E41ABD | ||||
| :402F4000A410A54204D056F8253098470135F8E700F0DEFD084B094C1E46E41AA4100025A54204D056F8253098470135F8E770BD1C3B00001C3B00001C3B0000243B0000BA | ||||
| :402F800003460244934202D003F8011BFAE7704730B5141E05469BB0184604DA8B232B604FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029305934FF6FF73009136 | ||||
| :402FC0000491ADF80E3002461E9B6946284600F073F8431CBCBF8B232B6014B1009B00221A701BB030BD000007B5009313460A46014603480068FFF7CBFF03B05DF804FB50 | ||||
| :403000006081FF1F2DE9F0478E6882469E420C46914698463ED88A8912F4906F3AD02568096902236F1A656905EB450595FBF3F57B1C43449D4238BF1D4653050FD5294638 | ||||
| :4030400000F04AFB064698B13A46216900F0D2FAA38923F4906343F08003A38113E02A4600F098FB064670B92169504600F0E8FA0C23CAF80030A3894FF0FF3043F0400332 | ||||
| :40308000A381BDE8F08726613E44266046466561ED1BA560464528BF464649463246206800F0B3FAA36800209B1BA36023681E442660BDE8F08700002DE9F04F9DB003930D | ||||
| :4030C0008B8980461C060D4616460DD50B695BB9402100F001FB2860286118B90C23C8F80030CDE040236B610023099320238DF82930DFF89CB130238DF82A3037463C465C | ||||
| :4031000014F8013B1BB9B7EB060910D003E0252BF9D02746F3E74B46324629464046FFF771FF013000F0A780099B4B4409933B78002B00F0A08000234FF0FF320493079372 | ||||
| :40314000059206938DF853301A930126052221784E4800F041FA671C049B38B14B4A3C46801A06FA00F018430490EFE7D90644BF20228DF853201A0744BF2B228DF85320CC | ||||
| :4031800022782A2A03D0079A00210A200BE0039A111D12680391002A10DA524243F00200079204900BE027463B780134303B092B03D800FB02320121F5E701B107923B78AF | ||||
| :4031C0002E2B1ED17B782A2B0AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E0002319460593781C0A2407463A780130303A092A03D804FB01210123F5E703B14A | ||||
| :40320000059103223978224800F0E6F940B14023CBEB000003FA00F0049B013718430490397806221B487E1C8DF8281000F0D4F988B1194B33B9039B073323F00703083323 | ||||
| :40324000039314E003AB00932A46144B04A94046AFF3008007E003AB00932A460F4B04A9404600F093F8B0F1FF3F824603D0099B5344099342E7AB895B0601D4099801E059 | ||||
| :403280004FF0FF301DB0BDE8F08F00BFEB3A0000F13A0000F53A000000000000053000002DE9F04791461F460A698B6806469342B8BF1346C9F8003091F843200C46DDF858 | ||||
| :4032C000208012B10133C9F800302368990642BFD9F800300233C9F80030256815F0060510D104F1190A07E00123524639463046C04701301AD00135E368D9F800209B1A7D | ||||
| :403300009D42F1DB94F843302268003318BF012392060FD5E118302081F843005A1C94F845102244023382F8431003E04FF0FF30BDE8F08704F1430239463046C047013017 | ||||
| :40334000F4D02268D9F80050E36802F00602042A08BF5D1B2269A3680CBF25EAE57500259342C4BF9B1AED184FF000091A344D4509D00123224639463046C0470130D5D0CC | ||||
| :4033800009F10109F3E70020BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9B01F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A40F0CA8081F84520FC | ||||
| :4033C000834955E0642A1ED0692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B8800A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F14205111D1960136803 | ||||
| :4034000084F84230A8E021681A6811F0800F02D0111D196008E011F0400F02F10401196002D0B2F9003000E01368002B3CDA2D225B4284F8432037E021681A6811F0800F93 | ||||
| :4034400002D0111D196007E011F0400F02F10401196001D0138800E01368227E5C496F2A14BF0A2208221BE078225A4984F845202268186812F0800F00F104051D6003D15E | ||||
| :40348000550601D5038800E00368D00744BF42F0200222601BB9226822F0200222601022002084F8430001E049490A226568002DA56008DB206820F0040020602BB9002D82 | ||||
| :4034C0007DD175460CE0002B79D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D1082A0BD12368DA0708D5236962689A42DEBF302305F8013C05F1FF35C5EB0E03A1 | ||||
| :4035000023612EE008681A6810F0800F496903D0101D1860136808E010F0400F02F104001860136801D0198000E0196000232361754616E01A68111D196015680021626806 | ||||
| :40354000284600F049F808B1401B6060636804E004F1420584F8422001232361002384F84330CDF800803B4603AA21463046FFF797FE013002D14FF0FF3026E023692A4606 | ||||
| :4035800039463046C0470130F5D023689B0710D5002504F1190907E001234A4639463046C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842B8BF184605E00B78D0 | ||||
| :4035C00004F1420584F842308AE705B0BDE8F0839F390000FC3A000010B5C9B202449042034605D01C7801308C42F8D1184610BD002010BD10B5431E0A44914204D011F847 | ||||
| :40360000014B03F8014FF8E710BD884210B501EB020301D8421E0BE09842FBD28118D21AD34204D013F8014D01F8014DF8E710BD994204D011F8014B02F8014FF8E710BD48 | ||||
| :4036400038B50546002944D051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B96360146030E0A3420DD92268A018834201BF18685B681218226063600C6023E0C7 | ||||
| :40368000A24203D813465A68002AF9D118681918A1420BD12168014458188242196013D110685268014419605A600DE002D90C232B6009E021686018824201BF10685268A1 | ||||
| :4036C0000918216062605C602846BDE8384000F098B838BDA092FF1F70B5CD1C25F0030508350C2D38BF0C25002D064601DBA94202D90C23336046E000F082F8234B1C6872 | ||||
| :403700001A462146A1B10B685B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B681360636018BF0C4615E00C464968E9E7174C23681BB9304600F052F8206029468B | ||||
| :40374000304600F04DF8431C18D0C41C24F00304A0420DD12560304600F053F804F10B00231D20F00700C31A0ED05A42E25070BD211A304600F034F80130EBD10C233360DD | ||||
| :40378000304600F03EF8002070BD00BFA092FF1F9C92FF1FF8B5074615460E4621B91146BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F027F885420ED929463846FFF7ED | ||||
| :4037C0008BFF044650B131462A46FFF713FF31463846FFF735FF01E03046F8BD2046F8BD38B5064C0023054608462360FDF7DCFB431C02D1236803B12B6038BD8493FF1F50 | ||||
| :403800007047704751F8040C0028BEBF091851F8043CC0180438704700000000050209020B020D020F021102130215027265706C792030782530327800686F6D696E6700B4 | ||||
| :40384000626567696E6E696E67207365656B2066726F6D20256420746F2025640066696E6973686564207365656B00796573006E6F00647269766520303A20257320647214 | ||||
| :4038800069766520313A2025730057616974696E6720666F72205553422E2E2E0055534220726561647900636F6D6D616E6420307825303278006661696C2025642B2564F5 | ||||
| :4038C0002B2564203D3D2025642C206E6F74202564007061737365643D256400756E64657272756E206166746572202564207061636B65747300636F756E743D2564206974 | ||||
| :403900003D256420643D256400636D645F777269746500703D25642063723D25642063773D256420663D256420773D256420696E6465783D256420756E64657272756E3D91 | ||||
| :40394000256400756E64657272756E2100737563636573730073746172742065726173696E670073746F702065726173696E670069646C65000051004010004051004030EB | ||||
| :403980000000000140001000140140000800400140000A004C01400002005001402000303132333435363738394142434445460000010000000400000010000100000004D2 | ||||
| :4039C0000000001028000000000104000100000000000000000157494E5553420000303030303100000000000000000012034D0053004600540031003000300001000000DE | ||||
| :403A000001000000083A000001000000D73A0000000000000000000001000000203A000001000000A93A000004000000423A0000000000000000000000000000403A0000F8 | ||||
| :403A4000FF00000001024000FF00000082024000FF00000003034000FF00000084034000FF00020304030904160346006C007500780045006E00670069006E0065002A03E3 | ||||
| :403A800043006F0077006C00610072006B00200054006500630068006E006F006C006F0067006900650073000009022E0001010080320904000004FF0000010705010240E2 | ||||
| :403AC0000000070582024000000705030340000A0705840340000A12010002FF0001080912006E0100020180014300232D302B2000686C4C0065666745464700303132339A | ||||
| :403B000034353637383961626364656600000000F8B500BFF8BC08BC9E4670475900000025100000F8B500BFF8BC08BC9E46704735000000483B0000C880FF1FA00000009F | ||||
| :403B40002012000000000000000000008893FF1FFF000000675000400C00000007000000FFFFFFFF7F8000003F0000000000007D00FA0000400000000090D003FF0000007E | ||||
| :403B80000000000000000000000000000000000000000000000000000000000000000000E93A000000000000000000000000000000000000000000000000000000000000E2 | ||||
| :403BC00000000000000000000000000000000000000000000000000000000000000000000081FF1F0000000000000000000000000000000000000000000000000000000026 | ||||
| :40068000D5D151461648FFF7FEFDBAF1000F00F00E81144B1B8807A8ADF81C3074E200BF19010000F900000091000000C50000008881FF1F77380000733800007A38000022 | ||||
| :4006C00092380000A5380000E181FF1FF281FF1FAF3800002438000026380000BE380000DA3800002838000094F86C0001F0D6FD606EFFF755FE02F0E7FBB24BDFF8E0825C | ||||
| :400700001A78002702F0FB021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0D5FB0220FFF7EEFC012141F6FF734FF48042084602F028FB84F8AA00FD | ||||
| :4007400001F04AFF08F807000137402FF8D1DFF894A200270AF199091FFA89F80137402F14BF3A4600221AF8010F22440623127E402101F065FF424646F24A519AF800005D | ||||
| :4007800001F070FF08F14008402F1FFA88F8E5D196F86D3033B100237372637A002BFCD00023737200234FF0FF32236062602372236894F8AA002344197E01F0C5FE94F87B | ||||
| :4007C000AA0001F083FE012194F8AA0001F056FE2368002BFCD0002398467360D6F80CA0012701F08BFFE368B4F86E20CAEB030393420DD367B1042195F8AA0001F0B0FEC5 | ||||
| :4008000094F8AA0001F0BCFE0028F9D107463072237AFBB96A682B689A4202D1002FE0D118E00220FFF770FC6968402209EB8111022000F0EDFD6A68634B01321340002B4F | ||||
| :40084000BEBF03F1FF3363F03F03013308F101086360C6E70220277AFFF756FC00221146022000F0D5FDFFB20220FFF74DFCFFF7BDFC37B15548FFF706FD0220FFF72AFDB4 | ||||
| :4008800006E0534B08A81B88ADF82030FFF710FD627A4146237A4F48FFF7F5FC01E24E48FFF7F1FCD4F86E7017F03F0701D00320F5E1012001F0F8FC95F86C0001F0EEFCF4 | ||||
| :4008C00002F002FB454BDFF818811A7842F004021A701A7842F001021A701A7802F0FE021A701A7802F0FE021A7002F0F1FA686EFFF756FD01214FF4804341F6FF7208462E | ||||
| :4009000001F0D8FC85F8AA0001F066FE08F807000137402FF8D1DFF8CC90002709F199031FFA83F804930137402F14BF3A46002219F8010F22440523127E402101F080FEB9 | ||||
| :40094000414646F24C4299F8000001F08BFE08F14008402F1FFA88F8E5D100274FF0FF33376098467360BB463B46D6F86E9037725FEA99190CBF4FF0010A4FF0000A216867 | ||||
| :40098000114A01310A40002ABCBF02F1FF3262F03F026068B8BF013282426BD02BB1227A002A76D16A7A002A73D12068049A059302EB8010BAF1000F16D040223F2102F0C9 | ||||
| :4009C000E3FA1CE09A6500403F000080E43800002A380000FE380000113900009C640040A081FF1F9F81FF1F014601370120FFF7DEFBC7EB0903D3F1000A4AEB030A21689F | ||||
| :400A0000AB4A01310A40002ABEBF02F1FF3262F03F02013222606268059B01322AD12A683F2A27D14FF00008C5F8048001F070FC85F808806B6895F8AA002B44197E01F0BC | ||||
| :400A400083FD95F8AA0001F041FD012195F8AA0001F014FD85F80980637A002BFCD04FF00008012086F8098001F05EFC404601F01BFC00E023B1237A5BB96B7A4BB90123A1 | ||||
| :400A8000626842453FF47BAF0BF1010BD5F8048075E701F043FC012001F006FC002001F043FC042194F8AA0001F05AFD94F8AA0001F066FD0028F9D196F8AA0001F0F4FC07 | ||||
| :400AC000737A327A0293012303920193CDF800A05B463A4649467748FFF7D5FBBAF1000F08D0FFF783FB237A63B17348FFF7CBFB0220D4E0B945F4D070490120FFF757FBF9 | ||||
| :400B00000137F7E76E48FFF7BEFB6E4B38E094F86C0001F0C3FB606EFFF742FC6A48FFF7B2FB00236372637A002BFCD0012001F0FBFB00237372637A002BFCD0002001F0AA | ||||
| :400B4000F3FB6248FFF79FFB614B19E0002084F85E00FFF725FC5F4B12E094F8683023B195F869200AB985F86C2094F869201AB113B9012385F86C305748FFF7CDFB574B39 | ||||
| :400B80001B88ADF8203008A8FFF792FB89E0FFF7B1FB02F07BF8002002F01EF82A2701F049FF002001F0ECFE3A46002108A802F0EBF917238DF820308DF8217001F09EFD75 | ||||
| :400BC000002001F047FB002002F0DAF8C82001F057FD0DF12200FFF721FB0DF13600FFF73EFB01F08BFD012002F0CAF8322001F047FD0DF12600FFF711FB0DF13A00FFF7D3 | ||||
| :400C00002EFB012001F026FB4FF4967001F038FD01F074FD0DF12E00FFF700FB0DF14200FFF71DFB002001F015FB4FF4967001F027FD01F063FD022002F0A2F8322001F05B | ||||
| :400C40001FFD0DEB0700FFF7E9FA0DF13E00FFF706FB012001F0FEFA4FF4967001F010FD01F04CFD0DF13200FFF7D8FA0DF14600FFF7F5FA002001F0EDFA4FF4967001F06F | ||||
| :400C8000FFFC01F03BFD002002F07AF8002384F85E3001F07DFF01F04FFE74E70120FFF719FB032000F07AFC0D48FFF7ECFA0DE43F0000801B3900004B3900003892FF1F04 | ||||
| :400CC000553900002C3800005D3900006B3900002E38000030380000F281FF1F32380000783900002DE9F04172B6884B61221A70A3F5F06301221A801924854A9C7092E8C5 | ||||
| :400D000003008033062283F8002283E80300522203F580731A707F4B7F4A1B787F4EDBB2137040F618027E4B00251A8041F2512223F8022C33784FF4F07003F0010343EAA5 | ||||
| :400D4000450502F0B9F8013C05F003052ED0032DF0D1744B4FF480721A8007221A70724A002548211570917002221D705D7103F8032C0422DA716D4A6D4C13786D4E43F049 | ||||
| :400D80000103137012F8013C062743F0030302F8013C2378012243F0800323705B4B1A70654A137843F02003137000E0FEE707FB056300219A881868013502F0E5F8072D53 | ||||
| :400DC000F5D15E485E4E002550F8041F05F1105303F1440221F0FF074533C9B20B4452005B0002329A4206D012F802EC12F801CC0EF807C0F5E7B0420D44E5D1514A00239D | ||||
| :400E000013609360136193614F4B504F1A68504BDFF888811A604F4B1A684F4B1A604F4A137843F002031370137C43F0020313742378A2F5863243F040032370413A1378DE | ||||
| :400E400043F010031370464A464B07CA03C31A80454A2833106843F8250C127903F8212C424A07CA03C31A80414AE83B07CA03C31A80404A083307CA03C31A803E4A3F4B12 | ||||
| :400E8000A2F5616203CBC2F8100EC2F8141E1378042043F008031370394B02F5AA521B783D78DBB298F80060EDB203F007010C321B091170F6B2537045F003033B7046F096 | ||||
| :400EC000030388F800302F4B48221A702E4A402313702E49937013729372082382F81F3220220A7048710A72294A0A20137001F0DDFB284B88F8006044223D70264D1A7039 | ||||
| :400F000094E80F0007C52B80BDE8F08100480040B00900480F010049A146004025420040224200400440004006400040A2430040A04300407D390000E8460040FCFFFF478E | ||||
| :400F40008400004800760040B8090048F846004020760040BC090048287600400350014070090048C05100407C09004884090048900900489C09004832510040A8090048D5 | ||||
| :400F8000CF0100491D51004001590040235B0040585B004076580040B0430040F946004008B501F0C5FF03680C2B00D1FEE7FEE7084908B50B68084A1844821A802A01DC5E | ||||
| :400FC000086005E001F0B4FF0C2303604FF0FF33184608BDCC80FF1F8893FF1F80B51148114B0025C0B1A3F1100192C922460439161BB74204D051F8046F42F8046BF7E7D1 | ||||
| :40100000114653F8046C8C1AA64202D041F8045BF9E701381033E5E701F090FFFFF706FAFEE700BF010000004C3B0000124A134B10B51A60124A134C1368134843F40073A8 | ||||
| :4010400013600023032B98BF54F823204FEA830188BF0E4A0133302B4250F3D10C4B1A780C4B1A700C4B084A1A60FFF73BFEBDE8104001F0EDB900BF0004FA050CED00E042 | ||||
| :4010800014ED00E0000000000080FF1FA10F0000BC760040C080FF1F08ED00E0F8B501F013FF4B4A01271378022643F001031370137C484C43F001031374474B02F5E352E3 | ||||
| :4010C0001F700B3203F8946C1378054603F07F031370002001F0EAFA2378404A03F0F90323701378384603F0DF03137023783B43237001F0DBFA282001F0D8FA384B3046E8 | ||||
| :401100001A7802F07F021A701A7802F0BF021A7023783343237001F0C9FA2378314A43F0040323700023137053702F4AFF2199540133092BFBD1284601F0CAFE072117206D | ||||
| :4011400001F0FCFA2949172001F0EAFA0721182001F0F4FA2649182001F0E2FA0721152001F0ECFA2349152001F0DAFA0721052001F0E4FA2049052001F0D2FA0721062008 | ||||
| :4011800001F0DCFA1D49062001F0CAFA0721084601F0D4FA1A49072001F0C2FA0721082001F0CCFA1749082001F0BAFA0021162001F0C4FA1449162001F0B2FA07210C20FD | ||||
| :4011C00001F0BCFABDE8F84010490C2001F0A8BAA5430040944300409D60004012600040F851004084600040AD92FF1F6B1A0000A5180000691A00009D190000C9190000FE | ||||
| :40120000F9190000311A0000711A0000E51A0000214B224A10B5187000231370204A40201370204A0F2413701F4A13701F4A13701F4A13701F4A13701F4B4FF400021A60B6 | ||||
| :401240004FF080721A604FF400121A6020221A601860802018604FF480701860174804704FF480001860164B1A70933B19B91A7802F0FE0202E01A7842F001021A70114B51 | ||||
| :4012800003221A70802203F8202C012001F014FE0D4B04221A7010BDC892FF1FCE92FF1FCC92FF1FCD92FF1FC992FF1FB892FF1FCB92FF1F4093FF1F00E100E09E60004062 | ||||
| :4012C0009C600040286000401260004070B5074C054623780E461BB9FFF7E0FE0123237031462846BDE87040FFF792BF7892FF1F0A4A002313700A4A13700A4A13700A4A82 | ||||
| :4013000013700A4A13700A4A13700A4A13700A4B03221A70802203F8202C7047CE92FF1FCC92FF1FCD92FF1FC992FF1FB892FF1FCB92FF1F4093FF1F28600040014B187899 | ||||
| :40134000704700BFCD92FF1F044B1A7802F0FF001AB118780022C0B21A707047CC92FF1F024A0C2303FB002040787047D492FF1F431E072B0CD8074A064B00010344805C33 | ||||
| :401380005B7800F00F0043EA0020023880B2704700207047FC5F00401A4A38B50C2303FB00231B79090C13F0800F00F1FF35044619BF8AB24FF480438BB24FF48042032DA2 | ||||
| :4013C00018D8DFE805F002070C110021084601F01BF80DE00021084600F0FAFF08E00021084600F0D9FF03E00021084600F0B8FF054B1855EDB2072D03D801F0EDF8034BBC | ||||
| :40140000185538BDD492FF1FA492FF1FAD92FF1F431E072B2DE9F0470446894615465CD82F4F0C2202FB0072D388DFF8B8A09BB2C3F500739D424FF00C0303FB007388BF8B | ||||
| :40144000D588DB7884BFC5F50075ADB2254A43EA15230601B354B244EBB28AF80130224B1A5C9846FF2A01D1FFF796FF0C2303FB047200215170B9F1000F28D03DB31B4FEC | ||||
| :40148000385D01F011F811232946FE2218F8040001F0D6F806F5C04278321FFA89F118F8040001F0DFF8124D18F80410385D01F04BF80121385D00F0E1FF735D43F0020316 | ||||
| :4014C0007355735D03F0FD037355BDE8F08703FB04746379DBB28AF80230BDE8F08700BFD492FF1FFC5F0040AD92FF1FA492FF1F706000402DE9F047044615468846002946 | ||||
| :4015000040D0431E072B3FD8FFF732FFA84203D22046FFF72DFF05461D4E335DFF2B03D141462046FFF738FFDFF868A027011AF8040000F0B9FF1223FE222946305D01F01E | ||||
| :401540007FF807F5C0411FFA88F27831305D01F089F8DFF84490315D1AF8040000F0F4FF01211AF8040000F089FF17F8093043F0020307F8093017F8093003F0FD0307F8E8 | ||||
| :40158000093002E00D4600E000252846BDE8F087AD92FF1FA492FF1F70600040431E072B0AD8064A0C2303FB002300225A705A79034BD2B200011A54704700BFD492FF1F5E | ||||
| :4015C000FE5F0040431E072B9FBF024B000108221A547047FE5F004030B51A4A1A491B4D0878138803449BB21380194A00231488D8B2A4B27CB1082B0CD050680078C0B2ED | ||||
| :40160000E85450680133013050601088013880B21080ECE718460B780E4C082B0E4A00D040B10E4D2B7883F080032B700F232370022301E0022323701370094B18700870CB | ||||
| :4016400030BD00BF4493FF1F4093FF1F00600040BC92FF1FB992FF1FCE92FF1FCA92FF1F4193FF1F074B02221A70074B80221A70064B0F221A70064A00231370054A012089 | ||||
| :4016800013707047CE92FF1FCA92FF1FB992FF1F4093FF1F4193FF1F30B5164B16491B780A8803F00F03023BDBB21A4492B20A80124C134A0020118889B279B173B155682D | ||||
| :4016C000215C013BC9B229705168DBB20131516011880130013989B21180ECE7094A1370094A137883F080031370084B0B221A7030BD00BF296000404493FF1F0060004010 | ||||
| :40170000BC92FF1F4193FF1FCA92FF1FB992FF1F064A06231370064A01201370054B80221A70054B00221A70704700BFCE92FF1FB992FF1FCA92FF1F4193FF1F054B9A68E5 | ||||
| :401740003AB19A68044910709A680988518000229A607047BC92FF1F4493FF1F08B5124B1A78D2B21A701B78DBB21A0602D50F4A137008BD0220FFF7E1FF0D4B1B7803F0CF | ||||
| :401780006003202B05D0402B06D043B900F012FC04E001F0A1FB01E000F046FD10B9034B03221A7008BD00BF28600040B992FF1F0060004008B5084A084B0120197813881C | ||||
| :4017C0000B449BB21380064B00221A70FFF7B6FF044B03221A7008BD4493FF1F4093FF1FCE92FF1FB992FF1F08B50C4B1B78DBB2042B07D0062B09D0022B0DD1BDE8084046 | ||||
| :40180000FFF7D8BFBDE80840FFF746BF0320FFF795FF034B03221A7008BD00BFCE92FF1FB992FF1F08B5054B002201201A70FFF785FF034B03221A7008BD00BFCE92FF1FCB | ||||
| :40184000B992FF1F08B50A4B1A7832B11A78094942F080020A7000221A70074B002201201A70FFF76BFF054B03221A7008BD00BFB892FF1F08600040CE92FF1FB992FF1FC1 | ||||
| :40188000074B1B78DBB2042B05D0062B05D0022B05D1FFF7A1BEFFF7C5BFFFF7D3BF7047CE92FF1F38B51D4C2378DBB2DD0634D518060AD503F00F03012B2ED1FFF74EFF43 | ||||
| :4018C000174B1B78190609D538BD5A0602D5FFF7D7FF03E09D0620D5FFF786FF23781B061BD4104B1A78104B1B7813430F4A13701278934211D10A4A0849154613782078EC | ||||
| :40190000DBB2000605D41378DBB20B700B7803F00F0328788342F1D138BD38BD28600040B992FF1FCA92FF1F4193FF1F29600040054A00231380054A916819B191680B701E | ||||
| :4019400092685380704700BF4493FF1FBC92FF1F0E4808B503889BB213B9FFF783FE13E00B4B02221A700B4B00221A70FFF7E0FF094AD1799379028843EA012392B293422A | ||||
| :4019800038BF0380FFF728FE012008BDBC92FF1FCE92FF1FCA92FF1F00600040084B01221A700F3B9B7C074B1A7B02F00302012A1EBFDA7B82F08002DA7301225A73704723 | ||||
| :4019C0000B600040D492FF1F094B02221A700F3B93F82230074B1A7E02F00302012A1EBFDA7E82F08002DA7601225A76704700BF0B600040D492FF1F0B4B04221A700F3B22 | ||||
| :401A000093F83230094B93F8242002F00302012A1EBF93F8272082F0800283F82720012283F82520704700BF0B600040D492FF1F0B4B08221A700F3B93F84230094B93F857 | ||||
| :401A4000302002F00302012A1EBF93F8332082F0800283F83320012283F83120704700BF0B600040D492FF1F7047FFF741BC0000F0B5184B184E19780C27C9B201234FF029 | ||||
| :401A8000000C31B3CA0720D5144A4FEA031E7244947850782040C5070DD507FB03652C79240608D5147804F0FE0414706D790C4CEDB204F80E50840706D507FB0364257960 | ||||
| :401AC0002D0658BF84F801C090700133DBB24908D7E7F0BD9F600040D492FF1F70600040FE5F004000F0ACBC70B50446184B88B003AA03F11006154618685968083303C5BA | ||||
| :401B0000B3422A46F7D11B782B70FCB12223237001AD03232846637000F08AFE002220461146AB5C08AC04EB131414F8144C03F00F03847008AC234413F8143C0132082A48 | ||||
| :401B4000C1700371417100F10400EAD108B070BDA73900002DE9F0431C4D01222E460C201F274FF0800E4FF0080C194B00FB02581401234418705F70164998F80590214449 | ||||
| :401B8000B9F1000F07D098F8044024064CBF887081F802C001E081F802E000FB0261CC880132E4B29C71CC88092AC4F30724DC71CC88E4B21C71C988C1F307215971D4D1CC | ||||
| :401BC000054BFF221A70BDE8F08300BFD492FF1F70600040FC5F00400A600040064B074A1B7802EBC30253681A7C824286BF03EBC003586900207047C892FF1F083A0000F6 | ||||
| :401C00002DE9F84F424B1A78002A7ED01878414D0138C0B2FFF7E2FFA8463F4AC3681478007ADFF800C1E4B203EBC0000C2600274FF0010E834268D01A78A24263D11CF82A | ||||
| :401C40000420597891425ED19A7893F8039002F07F0206FB02FA05EB0A01CF7093F802B009F0030981F804B093F803B005F80AB0B3F804A0A1F808A093F902A0BAF1000FB7 | ||||
| :401C80000BDAB9F1010F0CBF4FF007094FF00D0981F8059081F801E009E0B9F1010F0CBF4FF005094FF0090981F805904F704FEA02191A4906FB0282494481F802E0B2F807 | ||||
| :401CC00008A0CAF3072A81F800A0B2F808A05FFA8AFA81F801A0B2F806A011495FFA8AFA494481F806A0B2F80690C9F3072981F80790B2F806905FFA89F981F80490D288FB | ||||
| :401D0000C2F307224A71083394E7BDE8F88F00BFCD92FF1FD492FF1FC992FF1FFC5F004070600040BA92FF1F08B5064B18780138C0B2FFF753FF20B143681B7900EBC3008B | ||||
| :401D4000406908BDCD92FF1F00212DE9F84F0B464E4E0C2707FB01F401313219092933554FF000059370494CD3701381937253705371EFD118B1464B1D70464B1D70464B17 | ||||
| :401D80001A78002A7FD0187801250138C0B2FFF725FFA8464368DFF8F8E0DB790C2713F0400F3E4B4FF0000C1A7814BF42F0010202F0FE021A70027AD20007FB0541C368D1 | ||||
| :401DC00003EB02094B4531D093F802A00AF07F06AE4229D10E89B3F804B0B6B25E4538BFA1F808B01E7893F801B01EF80660B3451AD181F804A0DE780E7093F902A0DE78D4 | ||||
| :401E0000BAF1000F06F0030607DA012E0CBF07260D264E7181F8018006E0012E0CBF052609264E7181F801C00833CBE70135092DC3D1C1680A328B1C0A440C20083393423F | ||||
| :401E400009D013F8081C13F80A5C01F07F0100FB01418D72F2E7FFF767FF114B0121186000230C2000FB0142D3801289013113449BB203F00102134409299BB2F2D1BDE88C | ||||
| :401E8000F84FFFF767BEBDE8F88F00BFD492FF1FBA92FF1F4293FF1FCD92FF1FCB92FF1FD092FF1F114B1B7903F07F035A1E072A19D80F490C2202FB031291781B0141F08F | ||||
| :401EC000010191700021D170517841F002015170127912F0800F074A1A4414BF8D2389239370FFF715BC0020704700BF00600040D492FF1FFC5F004030B4194B1A7902F0D9 | ||||
| :401F00007F02531E072B27D8164B0C2404FB02339978154D01F0FE0199700021D97029461201505D114400F07F0050555A7802F0FD025A701A795B78120605D5012B01D168 | ||||
| :401F40008C7006E00D2303E0012B0CBF082309238B7030BCFFF7DCBB002030BC704700BF00600040D492FF1FFC5F004010B50D4B0D4C21791878C9B20138C0B2FFF72EFE81 | ||||
| :401F800043681B798B4201D2012909D8074A0848535CDBB24354A3780120DBB2535410BD002010BDCD92FF1F00600040BA92FF1F4293FF1F38B58A4A8A4C13780021DBB24F | ||||
| :401FC00021801806517840F18D800A2900F20581DFE811F05D00030103010301030103010B0003017E0003018200D3787C49012B09D17D4B1A787D4B03EBC2035B685B68B3 | ||||
| :402000006360122310E0CB78022B12D18878FFF7E5FD002800F0E180436863606368DA7863689B7843EA02232380BDE83840FFF78FBCCB78032B26D16D4B00228878D5B28F | ||||
| :40204000854209D3664A91786A4AEE2908BF1346634A917881B106E0187801320028F1D018780344EAE764499278097C914203D16248FFF739FD614B1A78002A00F0AD80B9 | ||||
| :402080001A78228018E0BDE8384000F025BF13F0030313D0022B40F0A0802380504B0C211B7903F07F02564B01FB02339A78554BD2B21A7000225A706360B6E70222228083 | ||||
| :4020C000514A11784F4AC9B2117053706260ACE7012323804D4BEFE70123238013794C4A1344E9E701390A2977D8DFE801F037764F76067676760A7620009378454ADBB2B5 | ||||
| :402100005AE0937803F0FF0153B9404B1A7891425FD01970404B01201870FFF715FE58E0481EC0B2FFF75AFD0028EED155E0FFF71DFF002851D02A4A384913791279DBB209 | ||||
| :40214000D2B20A70364A3249D25CCB5C9A4240D0314B01221A70FFF753FD3AE003F00303012B2BD009D3022B37D11D4B9B78002B33D1BDE83840FFF7BFBE194B9B78012B8E | ||||
| :402180002BD1214A137803F0FD0315E003F00303012B13D008D3022B1FD1114B9B78E3B9BDE83840FFF77EBE0D4B9B78012B14D1154A137843F0020313700AE0084B1A79FA | ||||
| :4021C0005AB998781B791749DBB2CA5C22EA0002CA54BDE83840FFF79BBA002038BD00BF00600040BC92FF1FC892FF1F083A00006C3A0000F4390000DF3A00006093FF1FEA | ||||
| :40220000D492FF1F7992FF1FCB92FF1FCD92FF1FBA92FF1FB892FF1FCC92FF1FC992FF1F4293FF1FCF92FF1F074B1A78120609D55B78012B06D1054B054A5A6012781A8093 | ||||
| :40224000FFF786BB0020704700600040BC92FF1FCC390000014B1870704700BF78640040014B1878704700BF6B650040014B1870704700BF79640040064A0123136002F631 | ||||
| :4022800088321268E0211064034A1170A2F540721360704780E100E000E400E0014B1870704700BF79650040014B1870704700BF7D64004073B515461E460B4C05230022D4 | ||||
| :4022C000019200920A4601461846237000F064F932462946207800F01FF90221207800F009F9207802B070BDD080FF1F064A0423136002F688321268E0219064034A1170F2 | ||||
| :40230000A2F202321360704780E100E002E400E0014B04221A60704700E100E0014B04221A60704780E100E0014B1870704700BF7B650040704738B505460078012428B18D | ||||
| :4023400000F062FD285D0134E4B2F8E738BD08B50D2000F059FDBDE808400A2000F054BDF7B516461F460B4C00230325019300930A4601462846257000F00EF93A463146E4 | ||||
| :40238000207800F0C9F80221207800F0B3F8207803B0F0BDE080FF1FF7B516461F460B4C00230225019300930A4601462846257000F0F2F83A463146207800F0ADF82946CC | ||||
| :4023C000207800F097F8207803B0F0BDE180FF1FF7B516461F460B4C00230125019300930A4601462846257000F0D6F83A463146207800F091F80221207800F07BF8207805 | ||||
| :4024000003B0F0BDE280FF1F73B515461E460B4C0023019300930A4601461846237000F0BBF832462946207800F076F80221207800F060F8207802B070BD00BFE380FF1F72 | ||||
| :40244000024B1878C0F38010704700BF8F450040074A7F23802113705170064A013BDBB202F80839002BF9D1034A1370704700BFE480FF1FF87B00400078004017280FD838 | ||||
| :40248000084B0001C25C11B142F0200201E002F0DF02C254C25C42F00102C25400207047012070471070004017280BD8064B0001C25C02F0FE02C254C25C02F0DF02C25451 | ||||
| :4024C00000207047012070471070004017280DD8074900010B4603441A7942F004021A71435C43F00103435400207047012070471070004017280BD8064A0001835C490093 | ||||
| :4025000003F0F10301F00E011943815400207047012070471070004041F6FF73994208BF4FF400519A4208BF4FF4005217289FBFC00000F1804000F5EC4081809ABFC28032 | ||||
| :40254000002001207047000017289FBF034B00011954002088BF0120704700BF1970004017289FBF054B00011A5C01F007019DBF1143195400200120704700BF147000404E | ||||
| :4025800017289FBF034B0001185C00F0070088BFFF20704714700040172810B51AD8C00001F07F0100F1804441EAC21204F5EC44D2B222709DF8082003F00F0343EA0213C5 | ||||
| :4025C000DBB263709DF80C30002003F00F03A370E07010BD012010BD10B500F075FC0A4A5378182B0AD91478013B5370E30003F1804303F5F0431B78137000E0FF2400F0A3 | ||||
| :4026000067FC204610BD00BFE480FF1F030610B5044611D400F058FC084AE300117803F1804303F5F04319705378147001335370BDE8104000F04CBC10BD00BFE480FF1F18 | ||||
| :4026400030B504060CD411F4704509D1C40004F1804404F5F0442180A270E370284630BD012030BD03065FBFC00000F1804000F5F04081805ABFC2800020012070470000CD | ||||
| :4026800038B50446084DB4F5004F05D9286800F013FCA4F50044F6E7034B58686043BDE8384000F009BC00BFEC80FF1F024B1B7A584300F001BC00BFEC80FF1F0E4B00F0E7 | ||||
| :4026C00003001A78490102F0FC02104318701A7801F0600142F080021A701A7802F07F021A701A7802F09F020A431A701A7842F010021A70704700BF83430040014B012238 | ||||
| :402700001A70704784430040044B00F00F021B6853F8220043F82210704700BF08ED00E0054A00F01F00126800F1100352F8230042F82310704700BF08ED00E000F01F0049 | ||||
| :4027400000F16040490100F56440C9B2017070470F4B10B50F4900240F205C609C60DC601C615C61FFF7D0FF0B4A136843F0040313600A4B4FF47A72DB68B3FBF2F3084A5C | ||||
| :402780001360084B4FF400421C60C3F8E82010BD7C92FF1FFD27000010E000E0EC80FF1F14E000E018E000E0024A136843F002031360704710E000E008B5FFF7F5FF034A7F | ||||
| :4027C000136843F00103136008BD00BF10E000E010B5054CA3691BB9FFF7BAFF0123A361BDE81040FFF7E8BF7C92FF1F024B1868C0F30040704700BF10E000E038B5FFF7EC | ||||
| :40280000F5FF012808D1054D002455F8243003B198470134052CF8D138BD00BF8092FF1F024B03EB80035868596070477C92FF1F134B144A1B78DBB20360127843EA0223B0 | ||||
| :40284000114A0360127843EA0243104A0360127843EA026303600E4B0E4A1B78DBB24360127843EA02230C4A4360127843EA02430A4A4360127843EA02634360704700BFF1 | ||||
| :402880000301004904010049EC460040020100490101004900010049050100490601004910B500F011FB204A044613780A2043F002031370137C43F00203137412F80A3C08 | ||||
| :4028C00043F0010302F80A3C937943F00103937102F5AB52137843F003031370134B18221A7013F8012C42F0400203F8012C13F8012C02F0FC0203F8012CCE2203F8062C7C | ||||
| :40290000A3F597530222183B1A70094A137843F008031370FFF7CAFE064B10222046BDE810401A6000F0D4BAAB4300400E5900402F5B004080E200E008B500F0C5FA0F4A3B | ||||
| :40294000137803F0FE031370A2F5AA521D3A137803F0FD031370137C03F0FD03137412F80A3C03F0FE0302F80A3C937903F0FE039371BDE8084000F0ABBA00BF0859004037 | ||||
| :40298000044A137803F03F0343EA8010C0B21070704700BF08590040082804D00A280CBF8223C22300E0422308380E4AC0B20428137098BF0C4B4FF0000298BF33F9101028 | ||||
| :4029C0000A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A8070470A590040B83900004A93FF1F4C93FF1F5093FF1F08B5102000F0A6F974 | ||||
| :402A000007210420FFF79AFE07490420FFF788FE064A0C20137843F006031370FFF7BCFF034B00221A8008BDF12A0000095900404893FF1F10B5054C23781BB9FFF7DCFF7A | ||||
| :402A400001232370BDE81040FFF72ABF9892FF1F044B1A7802F0FB021A701A7842F001021A7070470859004010B5084B1C7814F0010403D10028F9D0002404E02046FFF7A2 | ||||
| :402A800015FE024B1B78204610BD00BF09590040034A044B1B881088181A00B2704700BF5093FF1FA25B00400E4A13881BB223B111880A2309B2594301E00B4B19680B4B61 | ||||
| :402AC0001B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270474A93FF1F4C93FF1F4893FF1F7047000010B500F0E7F9214A0446137861 | ||||
| :402B00000A2043F001031370137C43F00103137412F80A3C43F0020302F80A3C937943F00203937102F5AA521832137843F003031370144B18221A7013F8012C42F0400201 | ||||
| :402B400003F8012C13F8012C02F0FC0203F8012CCE2203F8062CA3F597530222123B1A70094A137843F008031370FFF79FFD074B08222046BDE810401A6000F0A9B900BFB0 | ||||
| :402B8000AB43004006590040275B004080E200E008B500F099F90F4A137803F0FE031370A2F5AA52153A137803F0FE031370137C03F0FE03137412F80A3C03F0FD0302F87F | ||||
| :402BC0000A3C937903F0FD039371BDE8084000F07FB900BF00590040044A137803F03F0343EA8010C0B21070704700BF00590040082804D00A280CBF8223C22300E0422383 | ||||
| :402C000008380E4AC0B20428137098BF0C4B4FF0000298BF33F910100A4B88BF11461A8042F210734B4341F2883103F6C41393FBF1F305490B60054B1A8070470259004054 | ||||
| :402C4000C23900005693FF1F5C93FF1F5493FF1F08B5102000F084F807210320FFF76EFD07490320FFF75CFD064A0C20137843F006031370FFF7BCFF034B00221A8008BD33 | ||||
| :402C8000492D0000015900405893FF1F10B5054C23781BB9FFF7DCFF01232370BDE81040FFF728BF9992FF1F044B1A7802F0FB021A701A7842F001021A70704700590040D8 | ||||
| :402CC00010B5084B1C7814F0010403D10028F9D0002404E02046FFF7E9FC024B1B78204610BD00BF01590040034A044B1B881088181A00B2704700BF5493FF1FA05B004034 | ||||
| :402D00000E4A13881BB223B111880A2309B2594301E00B4B19680B4B1B88C01A42F2107300B203FB00F2022391FBF3F30028D8BF5B42134493FBF1F000B270475693FF1FD5 | ||||
| :402D40005C93FF1F5893FF1F70470000034A00F0F800137803431370704700BF02410040034A00F0F800137803431370704700BF06410040014B1870704700BF7A65004015 | ||||
| :402D8000014B1870704700BF7E64004073B515461E460B4C04230022019200920A46014618462370FFF7F8FB324629462078FFF7B3FB02212078FFF79DFB207802B070BDA7 | ||||
| :402DC000FC80FF1F074A0223136002F688321268E0215064044A11706FF440710A441360704700BF80E100E001E400E0014B1870704700BF7A640040014B1870704700BF9D | ||||
| :402E00007B64004000000000FEB5494652465B460EB40746244909688A46244A12682448022100F071F8030020480068C018204900F06AF8143883460121C9430C4601254A | ||||
| :402E4000002600F041F8814651460B7823400B705846013000F030F83800F04028400B78234003430B70584600F026F80136072EF2D9002001300138013001200B78234041 | ||||
| :402E800003430B705846043000F016F8484600F01FF800BF00BF00BF0EBC894692469B46FEBD00BFAFF30080D480FF1FF880FF1F00C20100000000000230800803D000BFAA | ||||
| :402EC00001380046FCD17047EFF3108072B6704780F31088704700BF094A137803F00303012B0AD0022B09D113790C2103F07F02044B01FB02339B7A00E013790020704714 | ||||
| :402F000000600040D492FF1F002902D0B0FBF1F0704708B14FF0FF3000F008B80029F8D00246B0FBF1F000FB11217047704700BF014B1868704700BF6081FF1F0E4B70B57A | ||||
| :402F40001E460E4C0025E41AA410A54204D056F8253098470135F8E700F0DEFD084B094C1E46E41AA4100025A54204D056F8253098470135F8E770BD243B0000243B00007F | ||||
| :402F8000243B00002C3B000003460244934202D003F8011BFAE7704730B5141E05469BB0184604DA8B232B604FF0FF301DE04FF40273ADF80C300CBF234604F1FF33029350 | ||||
| :402FC00005934FF6FF7300910491ADF80E3002461E9B6946284600F073F8431CBCBF8B232B6014B1009B00221A701BB030BD000007B5009313460A46014603480068FFF741 | ||||
| :40300000CBFF03B05DF804FB6081FF1F2DE9F0478E6882469E420C46914698463ED88A8912F4906F3AD02568096902236F1A656905EB450595FBF3F57B1C43449D4238BF75 | ||||
| :403040001D4653050FD5294600F04AFB064698B13A46216900F0D2FAA38923F4906343F08003A38113E02A4600F098FB064670B92169504600F0E8FA0C23CAF80030A38908 | ||||
| :403080004FF0FF3043F04003A381BDE8F08726613E44266046466561ED1BA560464528BF464649463246206800F0B3FAA36800209B1BA36023681E442660BDE8F087000061 | ||||
| :4030C0002DE9F04F9DB003938B8980461C060D4616460DD50B695BB9402100F001FB2860286118B90C23C8F80030CDE040236B610023099320238DF82930DFF89CB1302302 | ||||
| :403100008DF82A3037463C4614F8013B1BB9B7EB060910D003E0252BF9D02746F3E74B46324629464046FFF771FF013000F0A780099B4B4409933B78002B00F0A080002335 | ||||
| :403140004FF0FF3204930793059206938DF853301A930126052221784E4800F041FA671C049B38B14B4A3C46801A06FA00F018430490EFE7D90644BF20228DF853201A0773 | ||||
| :4031800044BF2B228DF8532022782A2A03D0079A00210A200BE0039A111D12680391002A10DA524243F00200079204900BE027463B780134303B092B03D800FB0232012141 | ||||
| :4031C000F5E701B107923B782E2B1ED17B782A2B0AD1039B02371A1D1B680392002BB8BF4FF0FF33059310E0002319460593781C0A2407463A780130303A092A03D804FB46 | ||||
| :4032000001210123F5E703B1059103223978224800F0E6F940B14023CBEB000003FA00F0049B013718430490397806221B487E1C8DF8281000F0D4F988B1194B33B9039BDF | ||||
| :40324000073323F007030833039314E003AB00932A46144B04A94046AFF3008007E003AB00932A460F4B04A9404600F093F8B0F1FF3F824603D0099B5344099342E7AB897F | ||||
| :403280005B0601D4099801E04FF0FF301DB0BDE8F08F00BFF33A0000F93A0000FD3A0000000000000D3000002DE9F04791461F460A698B6806469342B8BF1346C9F8003093 | ||||
| :4032C00091F843200C46DDF8208012B10133C9F800302368990642BFD9F800300233C9F80030256815F0060510D104F1190A07E00123524639463046C04701301AD001355B | ||||
| :40330000E368D9F800209B1A9D42F1DB94F843302268003318BF012392060FD5E118302081F843005A1C94F845102244023382F8431003E04FF0FF30BDE8F08704F1430253 | ||||
| :4033400039463046C0470130F4D02268D9F80050E36802F00602042A08BF5D1B2269A3680CBF25EAE57500259342C4BF9B1AED184FF000091A344D4509D0012322463946F2 | ||||
| :403380003046C0470130D5D009F10109F3E70020BDE8F0872DE9F04317460A7E85B06E2A984606460C460C9B01F1430E00F0AE8011D8632A22D009D8002A00F0BB80582A01 | ||||
| :4033C00040F0CA8081F84520834955E0642A1ED0692A1CD0C0E0732A00F0B08009D86F2A2ED0702A40F0B8800A6842F020020A603EE0752A24D0782A3AD0ADE01A6801F114 | ||||
| :403400004205111D1960136884F84230A8E021681A6811F0800F02D0111D196008E011F0400F02F10401196002D0B2F9003000E01368002B3CDA2D225B4284F8432037E0C5 | ||||
| :4034400021681A6811F0800F02D0111D196007E011F0400F02F10401196001D0138800E01368227E5C496F2A14BF0A2208221BE078225A4984F845202268186812F0800F0E | ||||
| :4034800000F104051D6003D1550601D5038800E00368D00744BF42F0200222601BB9226822F0200222601022002084F8430001E049490A226568002DA56008DB206820F0CC | ||||
| :4034C000040020602BB9002D7DD175460CE0002B79D07546B3FBF2F002FB1033CB5C05F8013D03460028F5D1082A0BD12368DA0708D5236962689A42DEBF302305F8013CF7 | ||||
| :4035000005F1FF35C5EB0E0323612EE008681A6810F0800F496903D0101D1860136808E010F0400F02F104001860136801D0198000E0196000232361754616E01A68111DFC | ||||
| :403540001960156800216268284600F049F808B1401B6060636804E004F1420584F8422001232361002384F84330CDF800803B4603AA21463046FFF797FE013002D14FF056 | ||||
| :40358000FF3026E023692A4639463046C0470130F5D023689B0710D5002504F1190907E001234A4639463046C0470130E7D00135E368039A9B1A9D42F2DBE068039B9842DC | ||||
| :4035C000B8BF184605E00B7804F1420584F842308AE705B0BDE8F083A7390000043B000010B5C9B202449042034605D01C7801308C42F8D1184610BD002010BD10B5431EF7 | ||||
| :403600000A44914204D011F8014B03F8014FF8E710BD884210B501EB020301D8421E0BE09842FBD28118D21AD34204D013F8014D01F8014DF8E710BD994204D011F8014B40 | ||||
| :4036400002F8014FF8E710BD38B50546002944D051F8043C0C1F002BB8BFE41800F0D4F81E4A1368114613B96360146030E0A3420DD92268A018834201BF18685B68121885 | ||||
| :40368000226063600C6023E0A24203D813465A68002AF9D118681918A1420BD12168014458188242196013D110685268014419605A600DE002D90C232B6009E021686018A3 | ||||
| :4036C000824201BF106852680918216062605C602846BDE8384000F098B838BDA092FF1F70B5CD1C25F0030508350C2D38BF0C25002D064601DBA94202D90C23336046E018 | ||||
| :4037000000F082F8234B1C681A462146A1B10B685B1B0ED40B2B03D90B60CC18CD501EE08C420BBF63684B681360636018BF0C4615E00C464968E9E7174C23681BB9304658 | ||||
| :4037400000F052F820602946304600F04DF8431C18D0C41C24F00304A0420DD12560304600F053F804F10B00231D20F00700C31A0ED05A42E25070BD211A304600F034F863 | ||||
| :403780000130EBD10C233360304600F03EF8002070BD00BFA092FF1F9C92FF1FF8B5074615460E4621B91146BDE8F840FFF798BF1AB9FFF749FF2846F8BD00F027F8854208 | ||||
| :4037C0000ED929463846FFF78BFF044650B131462A46FFF713FF31463846FFF735FF01E03046F8BD2046F8BD38B5064C0023054608462360FDF7DCFB431C02D1236803B13B | ||||
| :403800002B6038BD8493FF1F7047704751F8040C0028BEBF091851F8043CC0180438704700000000050209020B020D020F021102130215027265706C792030782530327881 | ||||
| :4038400000686F6D696E6700626567696E6E696E67207365656B2066726F6D20256420746F2025640066696E6973686564207365656B00796573006E6F00647269766520AA | ||||
| :40388000303A20257320647269766520313A2025730057616974696E6720666F72205553422E2E2E0055534220726561647900636F6D6D616E64203078253032780066610F | ||||
| :4038C000696C2025642B25642B2564203D3D2025642C206E6F74202564007061737365643D256400756E64657272756E206166746572202564207061636B65747300636FE8 | ||||
| :40390000756E743D256420693D256420643D256400636D645F777269746500703D25642063723D25642063773D256420663D256420773D256420696E6465783D2564207526 | ||||
| :403940006E64657272756E3D256400756E64657272756E2100737563636573730073746172742065726173696E670073746F702065726173696E670069646C650000510001 | ||||
| :4039800040100040510040300000000140001000140140000800400140000A004C014000020050014020003031323334353637383941424344454600000100000004000096 | ||||
| :4039C00000100001000000040000001028000000000104000100000000000000000157494E5553420000303030303100000000000000000012034D0053004600540031002A | ||||
| :403A0000300030000100000001000000103A000001000000DF3A0000000000000000000001000000283A000001000000B13A0000040000004A3A00000000000000000000E9 | ||||
| :403A400000000000483A0000FF00000001024000FF00000082024000FF00000003034000FF00000084034000FF00020304030904160346006C007500780045006E006700CA | ||||
| :403A800069006E0065002A0343006F0077006C00610072006B00200054006500630068006E006F006C006F0067006900650073000009022E0001010080320904000004FFC9 | ||||
| :403AC00000000107050102400000070582024000000705030340000A0705840340000A12010002FF0001080912006E0100020180014300232D302B2000686C4C00656667E2 | ||||
| :403B0000454647003031323334353637383961626364656600000000F8B500BFF8BC08BC9E467047590000002D100000F8B500BFF8BC08BC9E46704735000000503B0000FD | ||||
| :403B4000C880FF1FA00000002012000000000000000000008893FF1FFF000000675000400C00000007000000FFFFFFFF7F8000003F0000000000007D00FA000040000000DA | ||||
| :403B80000090D003FF0000000000000000000000000000000000000000000000000000000000000000000000F13A0000000000000000000000000000000000000000000078 | ||||
| :403BC000000000000000000000000000000000000000000000000000000000000000000000000000000000000081FF1F000000000000000000000000000000000000000026 | ||||
| :403C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084 | ||||
| :403C40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044 | ||||
| :403C80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 | ||||
| @@ -4098,49 +4098,49 @@ | ||||
| :40FF80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041 | ||||
| :40FFC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 | ||||
| :0200000480007A | ||||
| :400000000145004008520040015B0040016400400403014003050140050701404C0801404D090140530A0140460B0140580C0140530D01404E0E0140320F01401315014057 | ||||
| :40004000411601403A1701404F180140571901404D1A0140591B014009400140154101400B4201400843014003440140094501400A4601400D470140084801400B49014002 | ||||
| :40008000194C01400A4D014006500140045101407E0208410944108211021802600A61197C4027212D0A8740E24EE602EA029380E201E82080048E809380E609EE04027719 | ||||
| :4000C00003200614070708100A220B380C110D040E880F101214132016E41720180119381A0E1B011D021E141F382214232025042604270828772B202C162D3F2E4132F047 | ||||
| :40010000340F353F36F03AA8580459045B045C995F018201880189AA8B448DCC8E028F229030932295F196049A209B449C089D01A210A311A80AAA04AC0CAD88AE02B02048 | ||||
| :40014000B20EB30FB410B60FB7F0BE04D804D90BDB04DC99DF0100100230038104020518070209800A640D220E100F02100211101280168217141A801B941D241E121F105F | ||||
| :400180002010210822802404262028022B802C102E402F44310832903301348035083601371039903C043D203F82680269906D4078017C807E0181048D409201948096107C | ||||
| :4001C000978A98039C909D0C9E619F12A180A204A401A510A74DAB40B502B720C0FBC2FFC4FBCAF9CCFFCEFCDE01E240E608EE050108023804380504060109200A200B408E | ||||
| :400200000C040D800E10113A1220134015401620171019021A201B041E071F01203F2108240425062608277829082A202C022D082E38317F3580363F39023F1056085804BE | ||||
| :4002400059045B045C995D905F018202832084098612870788128B208C088D048E018F109012913F9412972099389A129B019C129D029F38A003A204A320A609A720A801D7 | ||||
| :40028000A904AA1CAB08AF38B01FB33FBA02D804D904DC99DF010082031804040522060209010A110B080C800D19101011201201130217291A011D021F0221012212250455 | ||||
| :4002C000260429222B122D082E202F4131083262348035043712380A39203A403C803D2A3F825B40600261808040900E9120928095029620980199229A029B09A080A108B4 | ||||
| :40030000A220A310A502A602A704A810AB01B340C0FFC2FFC47FCAFFCCFFCEFFD608D808E82509090D01110919211B161D051E011F2A280129203104320133033520371825 | ||||
| :400340003F11400146EC480C49FF4AFF4BFF50045609580459045A045B045C995D995F0162C08091820E84458698889889088C118D078E229098949899049A889B019E107E | ||||
| :40038000A098A306A404A501A601A702A840AA05AC98AF01B00FB107B210B4E0B508B820BA02BE04BF10C036C620C808C9FFCAFFCBFFCD20CEF0D110D804D904DA04DB047B | ||||
| :4003C000DC99DD09DF01E108E240E340E480E640E740000401620840090B0A020B040D8010A01120120213021720180419021A141B121F0820082201259026A027682840C1 | ||||
| :400400002A802B102F08322036803721382039403FA042104740480450105610574059405A205F406403664069406A806B016C046D056E407420768286508F049002912088 | ||||
| :40044000930594049547964499609B029C029D029F08A108A511A602A712AB40AD40C00FC28FC44FCA2BCCB4CE3CD012D204D61CD810E244E602EE0102020420060108010B | ||||
| :4004800009040A700B020C0F0D0F0E101204144E150418211A4E22082508264E27022A212C4E2F053301347F350637083A203B203F405608580459045B045C995D905F01E7 | ||||
| :4004C00080088304840686388726880889408C088D078F0890049126941A96209711981099269A209C089D019F38A008A110A301A402A511A604A726A926AE01AF02B23F5F | ||||
| :40050000B540B73FB808BB80BF10D804D904DB04DC99DF01016604040522070209090A040D080E400F061120120213061542170819201D081F08211022042305240A268036 | ||||
| :40054000270228022B102D012E042F0A320435203682370839603D423E103F065B4061406D806E108004C0FFC2FEC4BFCAFACCF2CEFCD608D808E4018010830489408D227C | ||||
| :4005800094209D02A140A520A704A842A920AD80AE02B188B303E284E6A4EA0DEE090102050409100A050B080C200E101108131014011701180D1C0A223024102501262003 | ||||
| :4005C00030203104320C33103403350336103708388239883E413F455608580B59045B045C995D905F0180028104831087208B388C048F2090019320953F99389B019F0756 | ||||
| :40060000A320A502A738A904AB08AF20B002B201B404B73FBE15D804D904DB04DC90DF0101800280070909020D080E080F01170619081A081B011D081E091F22218025440C | ||||
| :40064000278829022A482B042F20300A31A0370938A83A023E103F055B805D205F4067056B026E106F057F4086448740890A8A098C088D0490089380A280C0C9C2E8C43066 | ||||
| :40068000CA4FCCCFCEEFD638D830DE80E208E408E6C2EE03027703140477077708110A220BE40D100EE00F421111121E1388171419771A111D011E111F0E2011228823146E | ||||
| :4006C000251627212B142C112E442F14300F310F320F35F036F03A8A3B22420245E0480249FF4AFF4BFF4F83580459045A045B045C995D095F0183078608870488048907CA | ||||
| :400700008F0492069304970498019B019C049D089E08A00FA118A302A710AB04AF04B001B402B51FB60CBF10D804D904DB04DC09DF01012003100402055007100801092015 | ||||
| :400740000A020D020F0A130216021702180219221A021C221D431E021F452120240C2511274429022A022B552C102F4930103115328035043752382A3A813B803D243F82DB | ||||
| :400780004440450147104C405C805E2964426610672069806A406B026D80874089448A018D409281932094829666978A980199049A109C109D189EE39F17A284A310A401BE | ||||
| :4007C000A512A749C0F6C2DBC498CAFFCCFFCEFFD020D6F0D8F0E080E220E408E632EE030019030704110622070409080C440E110F041018126113041401160E1704181938 | ||||
| :4008000019071C801F1020FF2302251827012B042F043070311F320F34803F015608580459045B045C095D905F018002823883208620872088048A088B208D048E208F9022 | ||||
| :4008400091FF92209607973899F89A389B019E209F07A03FA320A504A620A748A838AA01AB20AC04AD02AE10AFF8B13FB23FB3E0D804D904DB04DC99DF01010202010310D3 | ||||
| :40088000048205140A560D020E220F08130216021716188019181A541B3D1E2022012420275029022B152F6931053240331035043752380A39203B823C243F8244024740E8 | ||||
| :4008C0005B8062406510662068016A206B096F0281108240878088018B088C108F04900E9120928093809420962099079A039B069C029D189E609F11A010A102A201A3406D | ||||
| :40090000A610A70FA901AB04AD02AF02B080B110B204C0FDC2FFC4F8CAFFCCFFCEFFD608D808E2C2E6C0E8A0ECA0EE011B011F083210330836843B40C630CCF0CE10308010 | ||||
| :400940003204364037023B043D20808087448E1096209740A108A604AD08AE80AF01CCF0CE60E260E640EA4051085520811096089F02A108A590A644B180D460E2808604E7 | ||||
| :4009800096089F02A5A0A640AA04E610EE2014808308C4045D025F80810484049880A308A501A901D6051B0498809D02A120A308A404A505A920AB80C60809040B080D80F8 | ||||
| :4009C0000F4087049D02A120A308A404A505A880AB04C20F25808B028D20A5A0AB02AE40C820EEC05304562071027F0289028A208B04A302D460DC80DE20060809010E04E1 | ||||
| :400A00000F401C085120570858406708850287408B049D02A120A308A404A501A980AF40C001C20DC601D407D801E0017310860492049310AA08B040B310DC01E801EC01D4 | ||||
| :400A400001010D010F0111011B011D0100FF01AB02021105BF0000A09F001F000000000000000000100000004000000000000000C0000000FF0000B84700470000010000D2 | ||||
| :400A8000800000028200820000000000000303000300000027001801270018010004000000050000000000000000000000000000000000000000000000000000000000001E | ||||
| :400000000145004008520040015B0040016400400101014003050140030701404E0801404A0901406C0A0140550B01405A0C0140490D01405A0E0140340F0140041701403E | ||||
| :40004000471801405A1901404F1A01404C1B01400C4001400A4101400F4201400D430140044401400C450140064601400C4701400F4801400B490140194C0140074D0140FA | ||||
| :4000800005500140045101407E02080509411080118219026006610A7C4027212A0AE280E640EA05EE10E620EA01EE8C00180220041806E009020A100C010E02100111076F | ||||
| :4000C00012041407150216F8170118801A181B011C181E4020FF260828012A062E072F0630FF330335043B083E01580459045B045C905F0181408210833085E18680870885 | ||||
| :4001000088018A248B108C7C8E828F1091FC92039302961097039B109D209E109FDCA180A210A330A401A648A9E1AA1CAB04AE10B01FB31FB4F0B7E0BA20D608D80BD90B5D | ||||
| :40014000DB04DC99DD90DF01012003A20404055208040AA10B010D080EA80F0210201280135015041680175919011A801B301E402180228424202514260429202B802F0167 | ||||
| :400180003180321433023614370138083B513D2058105980600A68026B046D4078018410884091209358942C9540970199729B599C019F04A240A301A58CA628A792A901F2 | ||||
| :4001C000AA10B010C0FFC2FDC4FFCA15CCEFCE2FD60CD80CDE01E622E804EE8C004801400311044805F10708081009100A200BE10C5A0E200F0E10C01201144818481C02F7 | ||||
| :400200001D201E041F112180224023112448288629F12A782B022DF12E042F04303F310F328033F0344038023B023E1440254520480249FF4AFF4BFF4D204EF0511058045A | ||||
| :40024000590B5A045B045C995D095F01610862406340648066406740800481018220830E8404861088808A048BC08D018E0291EF92029403952F96FC974099019A049B04BE | ||||
| :400280009C049D809E409F2FA0FFA101A302A404A6F9A710A804A901AA08AB08AC01AE02AF20B4FFB51FB7E0BE10D804D904DB04DC90DF01004401020204042405020606B2 | ||||
| :4002C000084809200A800B280D280E800F021180128813081408174918401A041B051F2023502680270829202B822C802E802F28318034403608375138083B513D903E02AA | ||||
| :4003000042044620470849014A0268056E507801830489108A808E409120928093209540965099729A829B519C019D019E209F04A090A160A242A308A405A50CA628A7130E | ||||
| :40034000A840AA01B540C0FFC2FFC4FFCAFDCCF8CEBFD004D208DE01E404E640EE1000800102027E044006100702083E09010A400C400E020F041040111812201320147E22 | ||||
| :400380001703188019021C401D081E04210222012502284029022A082D202F1830FF310833203507371039203E013F05400247EC483049FF4AFF4BFF5004560158045904C1 | ||||
| :4003C0005A045B045C905D095F0162C080368209842D8612880789028B018C3F9209961299019B029C24A104A480A640A840AA80AEC0B040B104B238B301B407B680B7021B | ||||
| :40040000B882B988BE41BF45D80BD904DB04DC09DF01001A010403820408060A07400A700B410C800D280E80102011501711189019A01C80202021402202253026802760C1 | ||||
| :4004400029012D022E202F11302036A939103C803D283F02472056056A806B016C946D806EA06F18768A780189C08A1091309323942895049620974099129E249F45A0205B | ||||
| :40048000A201A480A55CA668A79BA820A950AA80B080B640C0FFC2FDC457CAF1CCF4CEF4D020DE0100020140020C04100550072008040A080E010F10107211041280130203 | ||||
| :4004C000140E150816F018101B201C801E20201021602310244025022680270528102C082D072E0430FF310133703506370838023F445608580459045B045C995D905F0174 | ||||
| :40050000810C82078340840185808604870C88018A028B048C408EA08F02900191FF9457950397FC9840990C9A909B109C019D019E069F02A057A302A50CA7F1A840AB0883 | ||||
| :40054000AD0CAE08AF20B030B1FFB40FB6C0BF01D804D904DC09DF010220034904280540074009180A410C800D080E881004118812801604178119021A401D501E021F114A | ||||
| :400580002112224427802B922C842E602F103102321033043628374139043B413DA83E013F025880630169908A048E048F01C0FFC2FFC4DFCAFBCCF7CEFBD608D808E280A8 | ||||
| :4005C000E404E680EA08EE0B011406410714080109140A120B080CF10E040F201241150A16411714180119041A281C801D0A1E01211422412504264E29042B102D182F0158 | ||||
| :40060000320F3307353836F039083A085608580859045B045C995D905F018210846088018A048C7C8D018E02921C96039A109C409D04A210A401A608AA10AD02AE10B1016E | ||||
| :40064000B21FB304B440B502B620BF15D80BD904DB04DC09DF01012803810524070108100A120B800C200E060F50102011011280135014101501170418081A161E021F885A | ||||
| :4006800020202101221024042518262828022D062E802F0430043240330C35103608374039803D283E403F0258405A205D505F086401650867066A806C016F0378017F01D2 | ||||
| :4006C000814083088501912492489358940C96019702984299339A809B409C059D80A104A280A301A460A508A628A782AC02B048C0EFC2FFC43FCAF8CC78CEF8D67CD870F3 | ||||
| :40070000DE11E204E402E680EE0B01FC02900302042005C106C0072808C10A240B900CFC0E020F901120120313C018011A481B901E901F032290239C2690279029012A9012 | ||||
| :400740002B442E9C2F9031E034E0361F371F3A203B02420245E0480249FF4AFF4BFF4F83580B590B5A045B045C995D095F01821084618501860888618A04921096109A0394 | ||||
| :400780009C409E30A07CA202A61CA820AA50AC80B080B101B260B41FB660BE01BF01D808D904DB04DC09DF01012002C0036204080520074008020A050C400E0A0F50105066 | ||||
| :4007C0001350141015401608170519401B301C041D041E491F4022422780284029242A4830103242380A3B503F044110484059015A985F80600661406202632069806D40BA | ||||
| :4008000078017F018240900A9120921C9356958096019780980199219B059D04A281A302A440AD10B010B580C07FC2FBC4FFCA0FCC0DCE4FD004D61FD80FDE11E004EE085F | ||||
| :400840001A401F083328360437103A406A406B108B20C630CCF0CE1032043380364037023A013E809E40A604CCF0CE60502055108D2096089EC09F02A020A110A644A7809D | ||||
| :40088000A910AA01B420D460EAA08A809EC09F02A002A120A202A640A780AA06AE04B002EA80EE3014107310C404DC01530164108B1090109710B010B410D401D801E4017C | ||||
| :4008C000E808EA041B048301901097029C10C60808080B080E020F408710903097089C10A810AB04AF04C20F240280018A409A209E40A002A120A202AB02AE60AF80C820D3 | ||||
| :40090000E420EA10EED051205202722074029A20A002A120A202D4A0DC80DE2005400B200C800E401F40501056205C106120824084108B40903097209C10AA01AC08AF40A1 | ||||
| :40094000C001C20DC601D406D604D802E60182209E20AD40B120B480EC01EE0201010D010F0111011D0100FF01AB020211050000BF0000A09F001F0000000000000000004A | ||||
| :40098000100000004000000000000000C0000000FF0000B84700470000010000800000028200820000000000000303000300000027001801270018010004000000050000C9 | ||||
| :4009C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F7 | ||||
| :400A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B6 | ||||
| :400A40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076 | ||||
| :400A80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036 | ||||
| :400AC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F6 | ||||
| :400B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B5 | ||||
| :400B40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000075 | ||||
| @@ -4615,12 +4615,12 @@ | ||||
| :0200000490105A | ||||
| :04000000BC90ACAF55 | ||||
| :0200000490303A | ||||
| :02000000B5F257 | ||||
| :02000000861365 | ||||
| :0200000490402A | ||||
| :4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0 | ||||
| :400040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080 | ||||
| :400080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040 | ||||
| :4000C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 | ||||
| :0200000490501A | ||||
| :0C00000000012E16106900002E2FC65BB8 | ||||
| :0C00000000012E16106900002E2F967CC7 | ||||
| :00000001FF | ||||
| @@ -3432,6 +3432,6 @@ | ||||
| </ignored_deps> | ||||
| </CyGuid_495451fe-d201-4d01-b22d-5d3f5609ac37> | ||||
| <boot_component v="" /> | ||||
| <current_generation v="138" /> | ||||
| <current_generation v="150" /> | ||||
| </CyGuid_fec8f9e8-2365-4bdb-96d3-a4380222e01b> | ||||
| </CyXmlSerializer> | ||||
| @@ -1,7 +1,6 @@ | ||||
|  | ||||
| //`#start header` -- edit after this line, do not edit this line | ||||
| `include "cypress.v" | ||||
| `include "../SuperCounter/SuperCounter.v" | ||||
|  | ||||
| //`#end` -- edit above this line, do not edit this line | ||||
| // Generated on 12/11/2019 at 21:18 | ||||
| @@ -9,7 +8,7 @@ | ||||
| module Sampler ( | ||||
| 	output [2:0] debug_state, | ||||
| 	output reg [7:0] opcode, | ||||
| 	output  req, | ||||
| 	output  reg       req, | ||||
| 	input   clock, | ||||
| 	input   index, | ||||
| 	input   rdata, | ||||
| @@ -19,77 +18,62 @@ module Sampler ( | ||||
|  | ||||
| //`#start body` -- edit after this line, do not edit this line | ||||
|  | ||||
| localparam STATE_WAITING = 0; | ||||
| localparam STATE_OPCODE = 1; | ||||
| // NOTE: Reset pulse is used in both clock domains, and must be long enough | ||||
| // to be detected in both. | ||||
|  | ||||
| reg [0:0] state; | ||||
| reg [5:0] counter; | ||||
|  | ||||
| reg oldsampleclock; | ||||
| reg oldindex; | ||||
| reg oldrdata; | ||||
| reg index_q; | ||||
| reg rdata_q; | ||||
|  | ||||
| reg sampleclocked; | ||||
| reg indexed; | ||||
| reg rdataed; | ||||
| reg index_edge; | ||||
| reg rdata_edge; | ||||
|  | ||||
| assign req = (state == STATE_OPCODE); | ||||
| reg req_toggle; | ||||
|  | ||||
| always @(posedge clock) | ||||
| always @(posedge sampleclock) | ||||
| begin | ||||
|     if (reset) | ||||
|     begin | ||||
|         state <= STATE_WAITING; | ||||
|         opcode <= 0; | ||||
|         sampleclocked <= 0; | ||||
|         indexed <= 0; | ||||
|         rdataed <= 0; | ||||
|         oldsampleclock <= 0; | ||||
|         oldindex <= 0; | ||||
|         oldrdata <= 0; | ||||
|         index_edge <= 0; | ||||
|         rdata_edge <= 0; | ||||
|         index_q <= 0; | ||||
|         rdata_q <= 0; | ||||
|         counter <= 0; | ||||
|         req_toggle <= 0; | ||||
|     end | ||||
|     else | ||||
|     begin | ||||
|         /* Remember positive egdes for sampleclock, index and rdata. */ | ||||
|         /* Both index and rdata are active high -- positive-going edges | ||||
|          * indicate the start of an index pulse and read pulse, respectively. | ||||
|          */ | ||||
|           | ||||
|         index_edge <= index && !index_q; | ||||
|         index_q <= index; | ||||
|          | ||||
|         if (sampleclock && !oldsampleclock) | ||||
|             sampleclocked <= 1; | ||||
|         oldsampleclock <= sampleclock; | ||||
|         rdata_edge <= rdata && !rdata_q; | ||||
|         rdata_q <= rdata; | ||||
|          | ||||
|         if (index && !oldindex) | ||||
|             indexed <= 1; | ||||
|         oldindex <= index; | ||||
|          | ||||
|         if (rdata && !oldrdata) | ||||
|             rdataed <= 1; | ||||
|         oldrdata <= rdata; | ||||
|          | ||||
|         case (state) | ||||
|             STATE_WAITING: | ||||
|             begin | ||||
|                 if (sampleclocked) | ||||
|                 begin | ||||
|                     if (rdataed || indexed || (counter == 6'h3f)) | ||||
|                     begin | ||||
|                         opcode <= {rdataed, indexed, counter}; | ||||
|                         rdataed <= 0; | ||||
|                         indexed <= 0; | ||||
|                         counter <= 0; | ||||
|                         state <= STATE_OPCODE; | ||||
|                     end | ||||
|                     else | ||||
|                         counter <= counter + 1; | ||||
|                          | ||||
|                     sampleclocked <= 0; | ||||
|                 end | ||||
|             end | ||||
|              | ||||
|             STATE_OPCODE: /* opcode sent here */ | ||||
|             begin | ||||
|                 state <= STATE_WAITING; | ||||
|             end | ||||
|         endcase | ||||
|         if (rdata_edge || index_edge || (counter == 6'h3f)) begin | ||||
|             opcode <= { rdata_edge, index_edge, counter }; | ||||
|             req_toggle <= ~req_toggle; | ||||
|             counter <= 1;   /* remember to count this tick */ | ||||
|         end else begin | ||||
|             counter <= counter + 1; | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| reg req_toggle_q; | ||||
|  | ||||
| always @(posedge clock) | ||||
| begin | ||||
|     if (reset) begin | ||||
|         req_toggle_q <= 0; | ||||
|         req <= 0; | ||||
|     end else begin | ||||
|         req_toggle_q <= req_toggle; | ||||
|         req <= (req_toggle != req_toggle_q); | ||||
|     end | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -65,7 +65,7 @@ begin | ||||
|                 if (dataclocked) | ||||
|                 begin | ||||
|                     pulsepending <= opcode[7]; | ||||
|                     countdown <= opcode[5:0]; | ||||
|                     countdown <= opcode[5:0] - 1; /* compensate for delay in last tick */ | ||||
|                     state <= STATE_WRITING; | ||||
|                 end | ||||
|             end | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -537,14 +537,14 @@ static void cmd_write(struct write_frame* f) | ||||
|  | ||||
|     init_replay_dma(); | ||||
|     bool writing = false; /* to the disk */ | ||||
|     bool finished = false; | ||||
|     int packets = f->bytes_to_write / FRAME_SIZE; | ||||
|     bool finished = (packets == 0); | ||||
|     int count_written = 0; | ||||
|     int count_read = 0; | ||||
|     dma_writing_to_td = 0; | ||||
|     dma_reading_from_td = -1; | ||||
|     dma_underrun = false; | ||||
|  | ||||
|      | ||||
|     int old_reading_from_td = -1; | ||||
|     for (;;) | ||||
|     { | ||||
|   | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -39,7 +39,7 @@ CFLAGS += -Ilib -Idep/fmt -Iarch | ||||
| export OBJDIR = .obj | ||||
|  | ||||
| all: .obj/build.ninja | ||||
| 	@ninja -f .obj/build.ninja -v | ||||
| 	@ninja -f .obj/build.ninja | ||||
|  | ||||
| clean: | ||||
| 	@echo CLEAN | ||||
|   | ||||
| @@ -72,7 +72,7 @@ people who've had it work). | ||||
|  | ||||
| | Format                                   | Read? | Write? | Notes | | ||||
| |:-----------------------------------------|:-----:|:------:|-------| | ||||
| | [IBM PC compatible](doc/disk-ibm.md)     |  🦄   |   🦖   | and compatibles (like the Atari ST) | | ||||
| | [IBM PC compatible](doc/disk-ibm.md)     |  🦄   |   🦄   | and compatibles (like the Atari ST) | | ||||
| | [Acorn ADFS](doc/disk-acornadfs.md)      |  🦄   |   🦖*  | single- and double- sided           | | ||||
| | [Acorn DFS](doc/disk-acorndfs.md)        |  🦄   |   🦖*  |                                     | | ||||
| | [Ampro Little Board](doc/disk-ampro.md)  |  🦖   |   🦖*   |                                     | | ||||
|   | ||||
| @@ -13,6 +13,9 @@ class AesLanierDecoder : public AbstractDecoder | ||||
| public: | ||||
|     virtual ~AesLanierDecoder() {} | ||||
|  | ||||
| 	int getDecoderBands() const { return 4; } | ||||
| 	bool isInterleaved() const { return true; } | ||||
|  | ||||
|     RecordType advanceToNextRecord(); | ||||
|     void decodeSectorRecord(); | ||||
| }; | ||||
|   | ||||
| @@ -26,8 +26,8 @@ static Bytes reverse_bits(const Bytes& input) | ||||
|  | ||||
| AbstractDecoder::RecordType AesLanierDecoder::advanceToNextRecord() | ||||
| { | ||||
|     _sector->clock = _fmr->seekToPattern(SECTOR_PATTERN); | ||||
|     if (_fmr->eof() || !_sector->clock) | ||||
|     nanoseconds_t clock = _fmr->seekToPattern(SECTOR_PATTERN); | ||||
|     if (_fmr->eof() || !clock) | ||||
|         return UNKNOWN_RECORD; | ||||
|     return SECTOR_RECORD; | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ class Sector; | ||||
| class Fluxmap; | ||||
| class SectorSet; | ||||
|  | ||||
| class AmigaDecoder : public AbstractDecoder | ||||
| class AmigaDecoder : public AbstractMfmDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~AmigaDecoder() {} | ||||
|   | ||||
| @@ -23,8 +23,8 @@ static const FluxPattern SECTOR_PATTERN(48, AMIGA_SECTOR_RECORD); | ||||
|  | ||||
| AbstractDecoder::RecordType AmigaDecoder::advanceToNextRecord() | ||||
| { | ||||
|     _sector->clock = _fmr->seekToPattern(SECTOR_PATTERN); | ||||
|     if (_fmr->eof() || !_sector->clock) | ||||
|     _fmr->seekToPattern(SECTOR_PATTERN); | ||||
|     if (_fmr->eof()) | ||||
|         return UNKNOWN_RECORD; | ||||
|     return SECTOR_RECORD; | ||||
| } | ||||
| @@ -32,6 +32,8 @@ AbstractDecoder::RecordType AmigaDecoder::advanceToNextRecord() | ||||
| void AmigaDecoder::decodeSectorRecord() | ||||
| { | ||||
|     const auto& rawbits = readRawBits(AMIGA_RECORD_SIZE*16); | ||||
| 	if (rawbits.size() < (AMIGA_RECORD_SIZE*16)) | ||||
| 		return; | ||||
|     const auto& rawbytes = toBytes(rawbits).slice(0, AMIGA_RECORD_SIZE*2); | ||||
|     const auto& bytes = decodeFmMfm(rawbits).slice(0, AMIGA_RECORD_SIZE); | ||||
|  | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class Apple2Decoder : public AbstractDecoder | ||||
| class Apple2Decoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~Apple2Decoder() {} | ||||
|   | ||||
| @@ -68,7 +68,7 @@ uint8_t combine(uint16_t word) | ||||
| AbstractDecoder::RecordType Apple2Decoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return RecordType::SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -9,7 +9,8 @@ | ||||
| #define BROTHER_DATA_RECORD_CHECKSUM     3 | ||||
| #define BROTHER_DATA_RECORD_ENCODED_SIZE 415 | ||||
|  | ||||
| #define BROTHER_TRACKS_PER_DISK          78 | ||||
| #define BROTHER_TRACKS_PER_240KB_DISK    78 | ||||
| #define BROTHER_TRACKS_PER_120KB_DISK    39 | ||||
| #define BROTHER_SECTORS_PER_TRACK        12 | ||||
|  | ||||
| class Sector; | ||||
| @@ -20,6 +21,9 @@ class BrotherDecoder : public AbstractDecoder | ||||
| public: | ||||
|     virtual ~BrotherDecoder() {} | ||||
|  | ||||
| 	int getDecoderBands() const { return 2; } | ||||
| 	bool isInterleaved() const { return false; } | ||||
|  | ||||
|     RecordType advanceToNextRecord(); | ||||
|     void decodeSectorRecord(); | ||||
|     void decodeDataRecord(); | ||||
| @@ -28,8 +32,16 @@ public: | ||||
| class BrotherEncoder : public AbstractEncoder | ||||
| { | ||||
| public: | ||||
| 	BrotherEncoder(int format, int bias): | ||||
| 		_format(format), | ||||
| 		_bias(bias) | ||||
| 	{} | ||||
|  | ||||
| 	virtual ~BrotherEncoder() {} | ||||
|  | ||||
| private: | ||||
| 	int _format; | ||||
| 	int _bias; | ||||
| public: | ||||
|     std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors); | ||||
| }; | ||||
|   | ||||
| @@ -57,7 +57,7 @@ static int decode_header_gcr(uint16_t word) | ||||
| AbstractDecoder::RecordType BrotherDecoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return RecordType::SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -129,9 +129,25 @@ static int charToInt(char c) | ||||
| std::unique_ptr<Fluxmap> BrotherEncoder::encode( | ||||
| 	int physicalTrack, int physicalSide, const SectorSet& allSectors) | ||||
| { | ||||
| 	if ((physicalTrack < 0) || (physicalTrack >= BROTHER_TRACKS_PER_DISK) | ||||
|         || (physicalSide != 0)) | ||||
| 	int logicalTrack; | ||||
| 	if (physicalSide != 0) | ||||
| 		return std::unique_ptr<Fluxmap>(); | ||||
| 	physicalTrack -= _bias; | ||||
| 	switch (_format) | ||||
| 	{ | ||||
| 		case 120: | ||||
| 			if ((physicalTrack < 0) || (physicalTrack >= (BROTHER_TRACKS_PER_120KB_DISK*2)) | ||||
| 					|| (physicalTrack & 1)) | ||||
| 				return std::unique_ptr<Fluxmap>(); | ||||
| 			logicalTrack = physicalTrack/2; | ||||
| 			break; | ||||
|  | ||||
| 		case 240: | ||||
| 			if ((physicalTrack < 0) || (physicalTrack >= BROTHER_TRACKS_PER_240KB_DISK)) | ||||
| 				return std::unique_ptr<Fluxmap>(); | ||||
| 			logicalTrack = physicalTrack; | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	int bitsPerRevolution = 200000.0 / clockRateUs; | ||||
| 	const std::string& skew = sectorSkew.get(); | ||||
| @@ -146,10 +162,10 @@ std::unique_ptr<Fluxmap> BrotherEncoder::encode( | ||||
| 		double dataMs = headerMs + postHeaderSpacingMs; | ||||
| 		unsigned dataCursor = dataMs*1e3 / clockRateUs; | ||||
|  | ||||
| 		const auto& sectorData = allSectors.get(physicalTrack, 0, sectorId); | ||||
| 		const auto& sectorData = allSectors.get(logicalTrack, 0, sectorId); | ||||
|  | ||||
| 		fillBitmapTo(bits, cursor, headerCursor, { true, false }); | ||||
| 		write_sector_header(bits, cursor, physicalTrack, sectorId); | ||||
| 		write_sector_header(bits, cursor, logicalTrack, sectorId); | ||||
| 		fillBitmapTo(bits, cursor, dataCursor, { true, false }); | ||||
| 		write_sector_data(bits, cursor, sectorData->data); | ||||
| 	} | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class Commodore64Decoder : public AbstractDecoder | ||||
| class Commodore64Decoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~Commodore64Decoder() {} | ||||
|   | ||||
| @@ -55,7 +55,7 @@ static Bytes decode(const std::vector<bool>& bits) | ||||
| AbstractDecoder::RecordType Commodore64Decoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return RecordType::SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -55,7 +55,7 @@ static Bytes decode(const std::vector<bool>& bits) | ||||
| AbstractDecoder::RecordType DurangoF85Decoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return RecordType::SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class DurangoF85Decoder : public AbstractDecoder | ||||
| class DurangoF85Decoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~DurangoF85Decoder() {} | ||||
|   | ||||
| @@ -102,7 +102,7 @@ static uint16_t checksum(const Bytes& bytes) | ||||
| AbstractDecoder::RecordType Fb100Decoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(SECTOR_ID_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(SECTOR_ID_PATTERN, matcher); | ||||
|     if (matcher == &SECTOR_ID_PATTERN) | ||||
| 		return RecordType::SECTOR_RECORD; | ||||
| 	return RecordType::UNKNOWN_RECORD; | ||||
| @@ -132,4 +132,4 @@ void Fb100Decoder::decodeSectorRecord() | ||||
|     _sector->data.writer().append(id.slice(5, 12)).append(payload); | ||||
|  | ||||
|     _sector->status = (wantPayloadCrc == gotPayloadCrc) ? Sector::OK : Sector::BAD_CHECKSUM; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ class Sector; | ||||
| class Fluxmap; | ||||
| class Track; | ||||
|  | ||||
| class Fb100Decoder : public AbstractDecoder | ||||
| class Fb100Decoder : public AbstractFmDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~Fb100Decoder() {} | ||||
|   | ||||
| @@ -57,11 +57,11 @@ const FluxPattern FM_TRS80DAM1_PATTERN(16, 0xf56b); | ||||
|  | ||||
| /*  | ||||
|  * TRS80DAM2 record: | ||||
|  * flux:   XXXX-X-X-XX-XXX- = 0xf56c | ||||
|  * flux:   XXXX-X-X-XX-XXX- = 0xf56e | ||||
|  * clock:  X X - - - X X X  = 0xc7 | ||||
|  * data:    X X X X X - X - = 0xfa | ||||
|  */ | ||||
| const FluxPattern FM_TRS80DAM2_PATTERN(16, 0xf56c); | ||||
| const FluxPattern FM_TRS80DAM2_PATTERN(16, 0xf56e); | ||||
|  | ||||
| /* MFM record separator: | ||||
|  * 0xA1 is: | ||||
| @@ -92,7 +92,7 @@ const FluxMatchers ANY_RECORD_PATTERN( | ||||
| AbstractDecoder::RecordType IbmDecoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
|  | ||||
|     /* If this is the MFM prefix byte, the the decoder is going to expect three | ||||
|      * extra bytes on the front of the header. */ | ||||
|   | ||||
| @@ -205,6 +205,7 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode( | ||||
|  | ||||
| 			Bytes truncatedData = sectorData->data.slice(0, _parameters.sectorSize); | ||||
| 			bw += truncatedData; | ||||
| 			hexdump(std::cout, data.slice(0, 64)); | ||||
| 			uint16_t crc = crc16(CCITT_POLY, data); | ||||
| 			bw.write_be16(crc); | ||||
|  | ||||
|   | ||||
| @@ -29,7 +29,7 @@ struct IbmIdam | ||||
|     uint8_t crc[2]; | ||||
| }; | ||||
|  | ||||
| class IbmDecoder : public AbstractDecoder | ||||
| class IbmDecoder : public AbstractMfmDecoder | ||||
| { | ||||
| public: | ||||
|     IbmDecoder(unsigned sectorBase, bool ignoreSideByte=false, | ||||
|   | ||||
| @@ -127,7 +127,7 @@ uint8_t decode_side(uint8_t side) | ||||
| AbstractDecoder::RecordType MacintoshDecoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class MacintoshDecoder : public AbstractDecoder | ||||
| class MacintoshDecoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~MacintoshDecoder() {} | ||||
|   | ||||
| @@ -35,22 +35,15 @@ AbstractDecoder::RecordType MxDecoder::advanceToNextRecord() | ||||
|     { | ||||
|         /* First sector in the track: look for the sync marker. */ | ||||
|         const FluxMatcher* matcher = nullptr; | ||||
|         _sector->clock = _clock = _fmr->seekToPattern(ID_PATTERN, matcher); | ||||
|         _fmr->seekToPattern(ID_PATTERN, matcher); | ||||
|         readRawBits(32); /* skip the ID mark */ | ||||
|         _logicalTrack = decodeFmMfm(readRawBits(32)).reader().read_be16(); | ||||
|         _logicalTrack = decodeFmMfm(readRawBits(32)).slice(0, 32).reader().read_be16(); | ||||
|     } | ||||
|     else if (_currentSector == 10) | ||||
|     { | ||||
|         /* That was the last sector on the disk. */ | ||||
|         return UNKNOWN_RECORD; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         /* Otherwise we assume the clock from the first sector is still valid. | ||||
|          * The decoder framwork will automatically stop when we hit the end of | ||||
|          * the track. */ | ||||
|         _sector->clock = _clock; | ||||
|     } | ||||
|  | ||||
|     _currentSector++; | ||||
|     return SECTOR_RECORD; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  | ||||
| #include "decoders/decoders.h" | ||||
|  | ||||
| class MxDecoder : public AbstractDecoder | ||||
| class MxDecoder : public AbstractFmDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~MxDecoder() {} | ||||
|   | ||||
| @@ -57,7 +57,7 @@ static Bytes decode(const std::vector<bool>& bits) | ||||
| AbstractDecoder::RecordType Victor9kDecoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
| 	_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(ANY_RECORD_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_RECORD_PATTERN) | ||||
| 		return SECTOR_RECORD; | ||||
| 	if (matcher == &DATA_RECORD_PATTERN) | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class Victor9kDecoder : public AbstractDecoder | ||||
| class Victor9kDecoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~Victor9kDecoder() {} | ||||
|   | ||||
| @@ -18,7 +18,7 @@ AbstractDecoder::RecordType ZilogMczDecoder::advanceToNextRecord() | ||||
| { | ||||
| 	const FluxMatcher* matcher = nullptr; | ||||
|     _fmr->seekToIndexMark(); | ||||
| 	_sector->clock = _fmr->seekToPattern(SECTOR_START_PATTERN, matcher); | ||||
| 	_fmr->seekToPattern(SECTOR_START_PATTERN, matcher); | ||||
| 	if (matcher == &SECTOR_START_PATTERN) | ||||
| 		return SECTOR_RECORD; | ||||
| 	return UNKNOWN_RECORD; | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| class Sector; | ||||
| class Fluxmap; | ||||
|  | ||||
| class ZilogMczDecoder : public AbstractDecoder | ||||
| class ZilogMczDecoder : public AbstractGcrDecoder | ||||
| { | ||||
| public: | ||||
|     virtual ~ZilogMczDecoder() {} | ||||
|   | ||||
| @@ -258,6 +258,11 @@ void Bytes::writeToFile(const std::string& filename) const | ||||
|     f.close(); | ||||
| } | ||||
|  | ||||
| void Bytes::writeTo(std::ostream& stream) const | ||||
| { | ||||
| 	stream.write((const char*) cbegin(), size()); | ||||
| } | ||||
|  | ||||
| ByteReader Bytes::reader() const | ||||
| { | ||||
|     return ByteReader(*this); | ||||
|   | ||||
| @@ -57,6 +57,7 @@ public: | ||||
|     ByteWriter writer(); | ||||
|  | ||||
|     void writeToFile(const std::string& filename) const; | ||||
| 	void writeTo(std::ostream& stream) const; | ||||
|  | ||||
| private: | ||||
|     std::shared_ptr<std::vector<uint8_t>> _data; | ||||
|   | ||||
| @@ -16,22 +16,23 @@ void AbstractDecoder::decodeToSectors(Track& track) | ||||
|     Sector sector; | ||||
|     sector.physicalSide = track.physicalSide; | ||||
|     sector.physicalTrack = track.physicalTrack; | ||||
|     FluxmapReader fmr(*track.fluxmap); | ||||
|     FluxmapReader fmr(*track.fluxmap, getDecoderBands(), isInterleaved()); | ||||
|  | ||||
|     _track = &track; | ||||
|     _sector = §or; | ||||
|     _fmr = &fmr; | ||||
| 	_track->intervals = fmr.intervals(); | ||||
|  | ||||
|     beginTrack(); | ||||
|     for (;;) | ||||
|     { | ||||
|         Fluxmap::Position recordStart = fmr.tell(); | ||||
|         sector.clock = 0; | ||||
| 		sector.intervals = fmr.intervals(); | ||||
|         sector.status = Sector::MISSING; | ||||
|         sector.data.clear(); | ||||
|         sector.logicalSector = sector.logicalSide = sector.logicalTrack = 0; | ||||
|         RecordType r = advanceToNextRecord(); | ||||
|         if (fmr.eof() || !sector.clock) | ||||
|         if (fmr.eof() || sector.intervals.empty()) | ||||
|             return; | ||||
|         if ((r == UNKNOWN_RECORD) || (r == DATA_RECORD)) | ||||
|         { | ||||
| @@ -80,11 +81,11 @@ void AbstractDecoder::pushRecord(const Fluxmap::Position& start, const Fluxmap:: | ||||
|     RawRecord record; | ||||
|     record.physicalSide = _track->physicalSide; | ||||
|     record.physicalTrack = _track->physicalTrack; | ||||
|     record.clock = _sector->clock; | ||||
|     record.intervals = _sector->intervals; | ||||
|     record.position = start; | ||||
|  | ||||
|     _fmr->seek(start); | ||||
|     record.data = toBytes(_fmr->readRawBits(end, _sector->clock)); | ||||
|     record.data = toBytes(_fmr->readRawBits(end)); | ||||
|     _track->rawrecords.push_back(record); | ||||
|     _fmr->seek(here); | ||||
| } | ||||
|   | ||||
| @@ -44,7 +44,7 @@ public: | ||||
|     void pushRecord(const Fluxmap::Position& start, const Fluxmap::Position& end); | ||||
|  | ||||
|     std::vector<bool> readRawBits(unsigned count) | ||||
|     { return _fmr->readRawBits(count, _sector->clock); } | ||||
|     { return _fmr->readRawBits(count); } | ||||
|  | ||||
|     Fluxmap::Position tell() | ||||
|     { return _fmr->tell(); }  | ||||
| @@ -58,6 +58,9 @@ public: | ||||
| 	virtual std::set<unsigned> requiredSectors(Track& track) const; | ||||
|  | ||||
| protected: | ||||
| 	virtual int getDecoderBands() const = 0; | ||||
| 	virtual bool isInterleaved() const = 0; | ||||
|  | ||||
|     virtual void beginTrack() {}; | ||||
|     virtual RecordType advanceToNextRecord() = 0; | ||||
|     virtual void decodeSectorRecord() = 0; | ||||
| @@ -68,4 +71,25 @@ protected: | ||||
|     Sector* _sector; | ||||
| }; | ||||
|  | ||||
| class AbstractFmDecoder : public AbstractDecoder | ||||
| { | ||||
| protected: | ||||
| 	int getDecoderBands() const { return 2; } | ||||
| 	bool isInterleaved() const { return false; } | ||||
| }; | ||||
|  | ||||
| class AbstractMfmDecoder : public AbstractDecoder | ||||
| { | ||||
| protected: | ||||
| 	int getDecoderBands() const { return 3; } | ||||
| 	bool isInterleaved() const { return true; } | ||||
| }; | ||||
|  | ||||
| class AbstractGcrDecoder : public AbstractDecoder | ||||
| { | ||||
| protected: | ||||
| 	int getDecoderBands() const { return 3; } | ||||
| 	bool isInterleaved() const { return false; } | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include "decoders/fluxmapreader.h" | ||||
| #include "flags.h" | ||||
| #include "protocol.h" | ||||
| #include "kmedian.h" | ||||
| #include "fmt/format.h" | ||||
| #include <numeric> | ||||
| #include <math.h> | ||||
| @@ -30,6 +31,26 @@ static DoubleFlag minimumClockUs( | ||||
|     "Refuse to detect clocks shorter than this, to avoid false positives.", | ||||
|     0.75); | ||||
|  | ||||
| FluxmapReader::FluxmapReader(const Fluxmap& fluxmap): | ||||
| 	_fluxmap(fluxmap), | ||||
| 	_bytes(fluxmap.ptr()), | ||||
| 	_size(fluxmap.bytes()), | ||||
| 	_isInterleaved(false) | ||||
| { | ||||
| 	rewind(); | ||||
| } | ||||
|  | ||||
| FluxmapReader::FluxmapReader(const Fluxmap& fluxmap, int bands, bool isInterleaved): | ||||
| 	_fluxmap(fluxmap), | ||||
| 	_bytes(fluxmap.ptr()), | ||||
| 	_size(fluxmap.bytes()), | ||||
| 	_isInterleaved(isInterleaved) | ||||
| { | ||||
| 	for (unsigned ticks : optimalKMedian(fluxmap, bands)) | ||||
| 		_intervals.push_back(ticks * NS_PER_TICK); | ||||
| 	rewind(); | ||||
| } | ||||
|  | ||||
| uint8_t FluxmapReader::getNextEvent(unsigned& ticks) | ||||
| { | ||||
|     ticks = 0; | ||||
| @@ -65,8 +86,9 @@ unsigned FluxmapReader::findEvent(uint8_t target) | ||||
|     } | ||||
| } | ||||
|  | ||||
| unsigned FluxmapReader::readInterval(nanoseconds_t clock) | ||||
| unsigned FluxmapReader::readInterval() | ||||
| { | ||||
| 	nanoseconds_t clock = _intervals.front(); | ||||
|     unsigned thresholdTicks = (clock * pulseDebounceThreshold) / NS_PER_TICK; | ||||
|     unsigned ticks = 0; | ||||
|  | ||||
| @@ -94,7 +116,8 @@ static int findLowestSetBit(uint64_t value) | ||||
| } | ||||
|  | ||||
| FluxPattern::FluxPattern(unsigned bits, uint64_t pattern): | ||||
|     _bits(bits) | ||||
|     _bits(bits), | ||||
| 	_pattern(pattern) | ||||
| { | ||||
|     const uint64_t TOPBIT = 1ULL << 63; | ||||
|  | ||||
| @@ -251,9 +274,9 @@ void FluxmapReader::seekToIndexMark() | ||||
|     _pos.zeroes = 0; | ||||
| } | ||||
|  | ||||
| bool FluxmapReader::readRawBit(nanoseconds_t clockPeriod) | ||||
| bool FluxmapReader::readRawBit() | ||||
| { | ||||
|     assert(clockPeriod != 0); | ||||
|     assert(!_intervals.empty()); | ||||
|  | ||||
|     if (_pos.zeroes) | ||||
|     { | ||||
| @@ -261,30 +284,38 @@ bool FluxmapReader::readRawBit(nanoseconds_t clockPeriod) | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     nanoseconds_t interval = readInterval(clockPeriod)*NS_PER_TICK; | ||||
|     double clocks = (double)interval / clockPeriod + clockIntervalBias; | ||||
|     nanoseconds_t interval = readInterval()*NS_PER_TICK; | ||||
| 	int clocks = 0; | ||||
| 	while (clocks < _intervals.size()-1) | ||||
| 	{ | ||||
| 		float median = (_intervals[clocks] + _intervals[clocks+1])/2.0; | ||||
| 		if (interval < median) | ||||
| 			break; | ||||
| 		clocks++; | ||||
| 	} | ||||
|  | ||||
|     if (clocks < 1.0) | ||||
|         clocks = 1.0; | ||||
|     _pos.zeroes = (int)round(clocks) - 1; | ||||
| 	if (_isInterleaved) | ||||
| 		clocks++; | ||||
|     _pos.zeroes = clocks; | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| std::vector<bool> FluxmapReader::readRawBits(unsigned count, nanoseconds_t clockPeriod) | ||||
| std::vector<bool> FluxmapReader::readRawBits(unsigned count) | ||||
| { | ||||
|     std::vector<bool> result; | ||||
|     while (!eof() && count--) | ||||
|     { | ||||
|         bool b = readRawBit(clockPeriod); | ||||
|         bool b = readRawBit(); | ||||
|         result.push_back(b); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| std::vector<bool> FluxmapReader::readRawBits(const Fluxmap::Position& until, nanoseconds_t clockPeriod) | ||||
| std::vector<bool> FluxmapReader::readRawBits(const Fluxmap::Position& until) | ||||
| { | ||||
|     std::vector<bool> result; | ||||
|     while (!eof() && (_pos.bytes < until.bytes)) | ||||
|         result.push_back(readRawBit(clockPeriod)); | ||||
|         result.push_back(readRawBit()); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -41,6 +41,7 @@ private: | ||||
|     std::vector<unsigned> _intervals; | ||||
|     unsigned _length; | ||||
|     unsigned _bits; | ||||
| 	uint64_t _pattern; | ||||
|     unsigned _highzeroes; | ||||
|     bool _lowzero = false; | ||||
|  | ||||
| @@ -67,14 +68,8 @@ private: | ||||
| class FluxmapReader | ||||
| { | ||||
| public: | ||||
|     FluxmapReader(const Fluxmap& fluxmap): | ||||
|         _fluxmap(fluxmap), | ||||
|         _bytes(fluxmap.ptr()), | ||||
|         _size(fluxmap.bytes()) | ||||
|     { | ||||
|         rewind(); | ||||
|     } | ||||
|  | ||||
|     FluxmapReader(const Fluxmap& fluxmap); | ||||
|     FluxmapReader(const Fluxmap& fluxmap, int bands, bool isInterleaved); | ||||
|     FluxmapReader(const Fluxmap&& fluxmap) = delete; | ||||
|  | ||||
|     void rewind() | ||||
| @@ -98,7 +93,7 @@ public: | ||||
|  | ||||
|     uint8_t getNextEvent(unsigned& ticks); | ||||
|     unsigned findEvent(uint8_t bits); | ||||
|     unsigned readInterval(nanoseconds_t clock); /* with debounce support */ | ||||
|     unsigned readInterval(); /* with debounce support */ | ||||
|  | ||||
|     /* Important! You can only reliably seek to 1 bits. */ | ||||
|     void seek(nanoseconds_t ns); | ||||
| @@ -107,15 +102,19 @@ public: | ||||
|     nanoseconds_t seekToPattern(const FluxMatcher& pattern); | ||||
|     nanoseconds_t seekToPattern(const FluxMatcher& pattern, const FluxMatcher*& matching); | ||||
|  | ||||
|     bool readRawBit(nanoseconds_t clockPeriod); | ||||
|     std::vector<bool> readRawBits(unsigned count, nanoseconds_t clockPeriod); | ||||
|     std::vector<bool> readRawBits(const Fluxmap::Position& until, nanoseconds_t clockPeriod); | ||||
|     bool readRawBit(); | ||||
|     std::vector<bool> readRawBits(unsigned count); | ||||
|     std::vector<bool> readRawBits(const Fluxmap::Position& until); | ||||
|  | ||||
| 	const std::vector<nanoseconds_t> intervals() const { return _intervals; }; | ||||
|  | ||||
| private: | ||||
|     const Fluxmap& _fluxmap; | ||||
|     const uint8_t* _bytes; | ||||
|     const size_t _size; | ||||
|     Fluxmap::Position _pos; | ||||
| 	std::vector<nanoseconds_t> _intervals; | ||||
| 	const bool _isInterleaved; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -4,6 +4,9 @@ | ||||
|  | ||||
| Fluxmap& Fluxmap::appendBytes(const Bytes& bytes) | ||||
| { | ||||
| 	if (bytes.size() == 0) | ||||
| 		return *this; | ||||
|  | ||||
|     return appendBytes(&bytes[0], bytes.size()); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| #include <set> | ||||
| #include <cassert> | ||||
|  | ||||
| typedef int nanoseconds_t; | ||||
| typedef double nanoseconds_t; | ||||
| class Bytes; | ||||
|  | ||||
| extern double getCurrentTime(); | ||||
|   | ||||
| @@ -5,12 +5,15 @@ | ||||
| #include "sectorset.h" | ||||
| #include "imagereader/imagereader.h" | ||||
| #include "fmt/format.h" | ||||
| #include <algorithm> | ||||
| #include <ctype.h> | ||||
|  | ||||
| std::map<std::string, ImageReader::Constructor> ImageReader::formats = | ||||
| { | ||||
| 	{".adf", ImageReader::createImgImageReader}, | ||||
| 	{".d81", ImageReader::createImgImageReader}, | ||||
| 	{".img", ImageReader::createImgImageReader}, | ||||
| 	{".ima", ImageReader::createImgImageReader}, | ||||
| }; | ||||
|  | ||||
| static bool ends_with(const std::string& value, const std::string& ending) | ||||
|   | ||||
| @@ -75,7 +75,6 @@ void ImageWriter::writeCsv(const std::string& filename) | ||||
| 		"\"Logical track\"," | ||||
| 		"\"Logical side\"," | ||||
| 		"\"Logical sector\"," | ||||
| 		"\"Clock (ns)\"," | ||||
| 		"\"Header start (ns)\"," | ||||
| 		"\"Header end (ns)\"," | ||||
| 		"\"Data start (ns)\"," | ||||
| @@ -96,11 +95,10 @@ void ImageWriter::writeCsv(const std::string& filename) | ||||
| 				if (!sector) | ||||
| 					f << fmt::format(",,{},,,,,,,,MISSING\n", sectorId); | ||||
| 				else | ||||
| 					f << fmt::format("{},{},{},{},{},{},{},{},{},{},{}\n", | ||||
| 					f << fmt::format("{},{},{},{},{},{},{},{},{},{}\n", | ||||
| 						sector->logicalTrack, | ||||
| 						sector->logicalSide, | ||||
| 						sector->logicalSector, | ||||
| 						sector->clock, | ||||
| 						sector->headerStartTime, | ||||
| 						sector->headerEndTime, | ||||
| 						sector->dataStartTime, | ||||
|   | ||||
| @@ -46,7 +46,7 @@ public: | ||||
| 					if (sector) | ||||
| 					{ | ||||
| 						outputFile.seekp(sector->logicalTrack*trackSize + sector->logicalSide*headSize + sector->logicalSector*numBytes, std::ios::beg); | ||||
| 						outputFile.write((const char*) sector->data.cbegin(), sector->data.size()); | ||||
| 						sector->data.slice(0, numBytes).writeTo(outputFile); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										322
									
								
								lib/kmedian.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								lib/kmedian.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,322 @@ | ||||
| #include "globals.h" | ||||
| #include "fluxmap.h" | ||||
| #include "decoders/fluxmapreader.h" | ||||
| #include "protocol.h" | ||||
| #include "kmedian.h" | ||||
| #include <algorithm> | ||||
| #include <numeric> | ||||
| #include <math.h> | ||||
| #include <limits.h> | ||||
|  | ||||
| /* Implement a O(kn log n) method for optimal 1D K-median. The K-median problem | ||||
|  * consists of finding k clusters so that the sum of absolute distances from | ||||
|  * each of the n points to the closest cluster is minimized. | ||||
|  * | ||||
|  * GRØNLUND, Allan, et al. Fast exact k-means, k-medians and Bregman divergence | ||||
|  * clustering in 1d. arXiv preprint arXiv:1701.07204, 2017. | ||||
|  * | ||||
|  * The points all have one of a very small range of values (compared to the | ||||
|  * number of points). Since k-medians clustering is either a point or the mean | ||||
|  * of two points, we can then do calculations with n being the number of | ||||
|  * distinct points, rather than the number of points, so that O(kn log n) | ||||
|  * becomes much quicker in concrete terms. | ||||
|  * | ||||
|  * Finding the median takes O(log n) time instead of O(1) time, which increases | ||||
|  * the constant factor in front of the kn log n term. | ||||
|  */ | ||||
|  | ||||
| class KCluster | ||||
| { | ||||
| public: | ||||
|     struct CDF | ||||
|     { | ||||
|         int pointsSoFar; | ||||
|         KValue sumToHere; | ||||
|         KValue thisValue; | ||||
|     }; | ||||
|          | ||||
|     int uniquePoints;            /* number of unique points */ | ||||
|     std::vector<struct CDF> cdf; /* cumulative sum of points */ | ||||
|  | ||||
|     KCluster(const std::vector<KValue>& inputPoints) | ||||
|     { | ||||
|         std::vector<KValue> points = inputPoints; | ||||
|         std::sort(points.begin(), points.end()); | ||||
|  | ||||
|         KValue current = NAN; | ||||
|         int count = 0; | ||||
|         KValue sum = 0.0; | ||||
|         for (KValue point : points) | ||||
|         { | ||||
|             if (point != current) | ||||
|             { | ||||
|                 struct CDF empty = {0}; | ||||
|                 cdf.push_back(empty); | ||||
|             } | ||||
|  | ||||
|             sum += point; | ||||
|             count++; | ||||
|  | ||||
|             auto& thiscdf = cdf.back(); | ||||
|             thiscdf.pointsSoFar = count; | ||||
|             thiscdf.sumToHere = sum; | ||||
|             thiscdf.thisValue = point; | ||||
|             current = point; | ||||
|         } | ||||
|  | ||||
|         uniquePoints = cdf.size(); | ||||
|     } | ||||
|  | ||||
|     /* Determines the median point of all points between the ith category | ||||
|      * in cdf (inclusive), and the jth (exclusive). It's used to | ||||
|      * reconstruct clusters later. | ||||
|      */ | ||||
|  | ||||
|     KValue medianPoint(int i, int j) | ||||
|     { | ||||
|         if (i >= j) | ||||
|             return 0; | ||||
|  | ||||
|         int lowerCount = 0; | ||||
|         if (i > 0) | ||||
|             lowerCount = cdf[i-1].pointsSoFar; | ||||
|         int upperCount = cdf[j-1].pointsSoFar; | ||||
|  | ||||
|         /* Note, this is not the index, but number of points start inclusive, | ||||
|          * which is why the -1 has to be turned into +1. */ | ||||
|  | ||||
|         KValue medianPoint = (lowerCount + upperCount + 1) / 2.0; | ||||
|          | ||||
|         auto lowerMedian = std::lower_bound(cdf.begin(), cdf.end(), (int)medianPoint, | ||||
|             [&](const struct CDF& lhs, int rhs) { | ||||
|                 return lhs.pointsSoFar < rhs; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         if (((int)ceil(medianPoint) == (int)floor(medianPoint)) | ||||
|                 || ((int)floor(medianPoint) != lowerMedian->pointsSoFar)) | ||||
|             return lowerMedian->thisValue; | ||||
|         else | ||||
|             return (lowerMedian->thisValue + (lowerMedian+1)->thisValue) / 2.0; | ||||
|     } | ||||
|  | ||||
|     /* Find the (location of the) minimum value of each row of an nxn matrix in | ||||
|      * n log n time, given that the matrix is monotone (by the definition of | ||||
|      * Grønlund et al.) and defined by a function M that takes row and column | ||||
|      * as parameters. All boundary values are closed, [minRow, maxRow] | ||||
|      * p. 197 of | ||||
|      * AGGARWAL, Alok, et al. Geometric applications of a matrix-searching | ||||
|      * algorithm. Algorithmica, 1987, 2.1-4: 195-208. | ||||
|      */ | ||||
|  | ||||
|     void monotoneMatrixIndices(std::function<KValue(int, int)>& M, | ||||
|             int minRow, int maxRow, int minCol, int maxCol,  | ||||
|             std::vector<int>& Tout, | ||||
|             std::vector<KValue>& Dout) | ||||
|     { | ||||
|         if (maxRow == minRow) | ||||
|             return; | ||||
|  | ||||
|         int currentRow = minRow + (maxRow-minRow)/2; | ||||
|  | ||||
|         /* Find the minimum column for this row. */ | ||||
|  | ||||
|         KValue minValue = INT_MAX; | ||||
|         int minHere = minCol; | ||||
|         for (int i = minCol; i<=maxCol; i++) | ||||
|         { | ||||
|             KValue v = M(currentRow, i); | ||||
|             if (v < minValue) | ||||
|             { | ||||
|                 minValue = v; | ||||
|                 minHere = i; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (Tout[currentRow]) | ||||
|             throw std::runtime_error("tried to set a variable already set"); | ||||
|  | ||||
|         Tout[currentRow] = minHere; | ||||
|         Dout[currentRow] = M(currentRow, minHere); | ||||
|  | ||||
|         /* No lower row can have a minimum to the right of the current minimum. | ||||
|          * Recurse on that assumption. */ | ||||
|  | ||||
|         monotoneMatrixIndices(M, minRow, currentRow, minCol, minHere+1, Tout, Dout); | ||||
|  | ||||
|         /* And no higher row can have a minimum to the left. */ | ||||
|  | ||||
|         monotoneMatrixIndices(M, currentRow+1, maxRow, minHere, maxCol, Tout, Dout); | ||||
|     } | ||||
|  | ||||
|     /* If item is the first cdf value with count at | ||||
|      * or above i, returns the cumulative sum up to the ith entry of the | ||||
|      * underlying sorted points list. | ||||
|      */ | ||||
|  | ||||
|     KValue cumulativeAt(std::vector<struct CDF>::iterator item, int i) | ||||
|     { | ||||
|         KValue sumBelow = 0.0; | ||||
|         int numPointsBelow = 0; | ||||
|  | ||||
|         if (item != cdf.begin()) | ||||
|         { | ||||
|             sumBelow = (item-1)->sumToHere; | ||||
|             numPointsBelow = (item-1)->pointsSoFar; | ||||
|         } | ||||
|  | ||||
|         return sumBelow + item->thisValue*(i - numPointsBelow); | ||||
|     } | ||||
|  | ||||
|     /* Grønlund et al.'s CC function for the K-median problem. | ||||
|      * | ||||
|      * CC(i,j) is the cost of grouping points_i...points_j into one cluster | ||||
|      * with the optimal cluster point (the median point). By programming | ||||
|      * convention, the interval is half-open and indexed from 0, unlike the | ||||
|      * paper's convention of closed intervals indexed from 1. | ||||
|      * | ||||
|      * Note: i and j are indices onto weighted_cdf. So e.g. if i = 0, j = 2 and | ||||
|      * weighted cdf is [[2, 0, 0], [4, 2, 1], [5, 2, 2]], then that is the cost | ||||
|      * of clustering all points between the one described by the zeroth weighted | ||||
|      * cdf entry, and up to (but not including) the last. In other words, it's | ||||
|      * CC([0, 0, 1, 1], 0, 5). | ||||
|      */ | ||||
|  | ||||
|     KValue CC(int i, int j) | ||||
|     { | ||||
|         if (i >= j) | ||||
|             return 0; | ||||
|  | ||||
|         int lowerCount = 0; | ||||
|         if (i > 0) | ||||
|             lowerCount = cdf[i-1].pointsSoFar; | ||||
|         int upperCount = cdf[j-1].pointsSoFar; | ||||
|  | ||||
|         /* Note, this is not the index, but number of points start inclusive, | ||||
|          * which is why the -1 has to be turned into +1. */ | ||||
|  | ||||
|         KValue medianPoint = (lowerCount + upperCount + 1) / 2.0; | ||||
|          | ||||
|         auto lowerMedian = std::lower_bound(cdf.begin(), cdf.end(), (int)medianPoint, | ||||
|             [&](const struct CDF& lhs, int rhs) { | ||||
|                 return lhs.pointsSoFar < rhs; | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         KValue mu; | ||||
|         if (((int)ceil(medianPoint) == (int)floor(medianPoint)) | ||||
|                 || ((int)floor(medianPoint) != lowerMedian->pointsSoFar)) | ||||
|             mu = lowerMedian->thisValue; | ||||
|         else | ||||
|             mu = (lowerMedian->thisValue + (lowerMedian+1)->thisValue) / 2.0; | ||||
|  | ||||
|         /* Lower part: entry i to median point between i and j, median excluded. */ | ||||
|  | ||||
|         int sumBelow = cumulativeAt(lowerMedian, (int)medianPoint); | ||||
|         if (i > 0) | ||||
|             sumBelow -= cdf[i-1].sumToHere; | ||||
|  | ||||
|         /* Upper part: everything from the median up, including the median if it's a | ||||
|          * real point. */ | ||||
|  | ||||
|         int sumAbove = cdf[j-1].sumToHere - cumulativeAt(lowerMedian, (int)medianPoint); | ||||
|  | ||||
|         return floor(medianPoint - lowerCount)*mu - sumBelow + sumAbove - ceil(upperCount - medianPoint)*mu; | ||||
|     } | ||||
|  | ||||
|     /* D_previous is the D vector for (i-1) clusters, or empty if i < 2. | ||||
|      * It's possible to do this even faster (and more incomprehensibly). | ||||
|      * See Grønlund et al. for that. */ | ||||
|  | ||||
|     /* Calculate C_i[m][j] given D_previous = D[i-1]. p. 4 */ | ||||
|  | ||||
|     KValue C_i(int i, const std::vector<KValue>& D_previous, int m, int j) | ||||
|     { | ||||
|         KValue f; | ||||
|         if (i == 1) | ||||
|             f = CC(0, m); | ||||
|         else | ||||
|             f = D_previous[std::min(j, m)] + CC(j, m); | ||||
|         return f; | ||||
|     } | ||||
|  | ||||
|     /* Calculates the optimal cluster centres for the points. */ | ||||
|  | ||||
|     std::vector<KValue> optimalKMedian(int numClusters) | ||||
|     { | ||||
|         std::vector<std::vector<int>> T(numClusters+1, std::vector<int>(uniquePoints+1, 0)); | ||||
|         std::vector<std::vector<KValue>> D(numClusters+1, std::vector<KValue>(uniquePoints+1, 0.0)); | ||||
|  | ||||
|         for (int i=1; i<numClusters+1; i++) | ||||
|         { | ||||
|             /* Stop if we achieve optimal clustering with fewer clusters than the | ||||
|              * user asked for. */ | ||||
|              | ||||
|             std::vector<KValue>& lastD = D[i-1]; | ||||
|             if ((i != 1) && (lastD.back() == 0.0)) | ||||
|                 continue; | ||||
|  | ||||
|             std::function<KValue(int, int)> M = [&](int m, int j) { | ||||
|                 return C_i(i, lastD, m, j); | ||||
|             }; | ||||
|  | ||||
|             monotoneMatrixIndices(M, i, uniquePoints+1, i-1, uniquePoints+1, | ||||
|                 T[i], D[i]); | ||||
|         } | ||||
|  | ||||
|         /* Backtrack. The last cluster has to encompass everything, so the | ||||
|          * rightmost boundary of the last cluster is the last point in the | ||||
|          * array, hence given by the last position of T. Then the previous | ||||
|          * cluster transition boundary is given by where that cluster starts, | ||||
|          * and so on. | ||||
|          */ | ||||
|  | ||||
|         int currentClusteringRange = uniquePoints; | ||||
|         std::vector<KValue> centres; | ||||
|  | ||||
|         for (int i=numClusters; i>0; i--) | ||||
|         { | ||||
|             int newClusteringRange = T[i][currentClusteringRange]; | ||||
|  | ||||
|             /* Reconstruct the cluster that's the median point between | ||||
|              * new_cluster_range and cur_clustering_range. */ | ||||
|  | ||||
|             centres.push_back(medianPoint(newClusteringRange, currentClusteringRange)); | ||||
|             currentClusteringRange = newClusteringRange; | ||||
|         } | ||||
|      | ||||
|         std::sort(centres.begin(), centres.end()); | ||||
|         return centres; | ||||
|     } | ||||
|  | ||||
| }; | ||||
|      | ||||
| static std::vector<KValue> getPointsFromFluxmap(const Fluxmap& fluxmap) | ||||
| { | ||||
|     FluxmapReader fmr(fluxmap); | ||||
|     std::vector<KValue> points; | ||||
|     while (!fmr.eof()) | ||||
|     { | ||||
|         KValue point = fmr.findEvent(F_BIT_PULSE); | ||||
|         points.push_back(point); | ||||
|     } | ||||
|     return points; | ||||
| } | ||||
|  | ||||
| /* Analyses the fluxmap and determines the optimal cluster centres for it. The | ||||
|  * number of clusters is taken from the size of the output array. */ | ||||
|  | ||||
| std::vector<KValue> optimalKMedian(const std::vector<KValue>& points, int clusters) | ||||
| { | ||||
|     KCluster kcluster(points); | ||||
|     return kcluster.optimalKMedian(clusters); | ||||
| } | ||||
|  | ||||
| std::vector<unsigned> optimalKMedian(const Fluxmap& fluxmap, int clusters) | ||||
| { | ||||
| 	 std::vector<unsigned> ticks; | ||||
|      for (KValue t : optimalKMedian(getPointsFromFluxmap(fluxmap), clusters)) | ||||
| 	 	ticks.push_back(t); | ||||
| 	return ticks; | ||||
| } | ||||
|  | ||||
							
								
								
									
										10
									
								
								lib/kmedian.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/kmedian.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef KMEDIAN_H | ||||
| #define KMEDIAN_H | ||||
|  | ||||
| typedef float KValue; | ||||
|  | ||||
| extern std::vector<KValue> optimalKMedian(const std::vector<KValue>& points, int clusters); | ||||
| extern std::vector<unsigned> optimalKMedian(const Fluxmap& fluxmap, int clusters); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @@ -107,7 +107,7 @@ void Track::readFluxmap() | ||||
| 	fluxmap = fluxsource->readFlux(physicalTrack, physicalSide); | ||||
| 	std::cout << fmt::format( | ||||
| 		"{0} ms in {1} bytes\n", | ||||
|             int(fluxmap->duration()/1e6), | ||||
|             fluxmap->duration()/1e6, | ||||
|             fluxmap->bytes()); | ||||
| 	if (outputFluxSink) | ||||
| 		outputFluxSink->writeFlux(physicalTrack, physicalSide, *fluxmap); | ||||
| @@ -195,10 +195,26 @@ void readDiskCommand(AbstractDecoder& decoder) | ||||
| 				std::cout << fmt::format("{} records, {} sectors; ", | ||||
| 					track->rawrecords.size(), | ||||
| 					track->sectors.size()); | ||||
| 				if (track->sectors.size() > 0) | ||||
| 					std::cout << fmt::format("{:.2f}us clock ({:.0f}kHz); ", | ||||
| 						track->sectors.begin()->clock / 1000.0, | ||||
|                         1000000.0 / track->sectors.begin()->clock); | ||||
|  | ||||
| 				const std::vector<nanoseconds_t>& intervals = track->intervals; | ||||
| 				bool first = true; | ||||
| 				for (nanoseconds_t i : intervals) | ||||
| 				{ | ||||
| 					if (!first) | ||||
| 						std::cout << "/"; | ||||
| 					first = false; | ||||
| 					std::cout << fmt::format("{:.2f}", i / 1000.0); | ||||
| 				} | ||||
| 				std::cout << " us or "; | ||||
| 				first = true; | ||||
| 				for (nanoseconds_t i : intervals) | ||||
| 				{ | ||||
| 					if (!first) | ||||
| 						std::cout << "/"; | ||||
| 					first = false; | ||||
| 					std::cout << fmt::format("{:.0f}", 1000000.0 / i); | ||||
| 				} | ||||
| 				std::cout << fmt::format(" kHz interval\n"); | ||||
|  | ||||
| 				for (auto& sector : track->sectors) | ||||
| 				{ | ||||
| @@ -251,8 +267,7 @@ void readDiskCommand(AbstractDecoder& decoder) | ||||
| 			std::cout << "\nRaw (undecoded) records follow:\n\n"; | ||||
| 			for (auto& record : track->rawrecords) | ||||
| 			{ | ||||
| 				std::cout << fmt::format("I+{:.2f}us with {:.2f}us clock\n", | ||||
|                             record.position.ns() / 1000.0, record.clock / 1000.0); | ||||
| 				std::cout << fmt::format("I+{:.2f}us\n", record.position.ns() / 1000.0); | ||||
| 				hexdump(std::cout, record.data); | ||||
| 				std::cout << std::endl; | ||||
| 			} | ||||
| @@ -261,13 +276,13 @@ void readDiskCommand(AbstractDecoder& decoder) | ||||
|         if (dumpSectors) | ||||
|         { | ||||
|             std::cout << "\nDecoded sectors follow:\n\n"; | ||||
|             for (auto& i : readSectors) | ||||
|             for (auto& sector : track->sectors) | ||||
|             { | ||||
|                 auto& sector = i.second; | ||||
| 				std::cout << fmt::format("{}.{:02}.{:02}: I+{:.2f}us with {:.2f}us clock\n", | ||||
|                             sector->logicalTrack, sector->logicalSide, sector->logicalSector, | ||||
|                             sector->position.ns() / 1000.0, sector->clock / 1000.0); | ||||
| 				hexdump(std::cout, sector->data); | ||||
| 				std::cout << fmt::format("{}.{:02}.{:02}: I+{:.2f}us: status {}\n", | ||||
|                             sector.logicalTrack, sector.logicalSide, sector.logicalSector, | ||||
|                             sector.position.ns() / 1000.0, | ||||
| 							sector.status); | ||||
| 				hexdump(std::cout, sector.data); | ||||
| 				std::cout << std::endl; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ public: | ||||
| 	RawRecord() {} | ||||
|  | ||||
| 	Fluxmap::Position position; | ||||
| 	nanoseconds_t clock = 0; | ||||
| 	std::vector<nanoseconds_t> intervals; | ||||
|     int physicalTrack = 0; | ||||
|     int physicalSide = 0; | ||||
| 	Bytes data; | ||||
|   | ||||
| @@ -26,7 +26,7 @@ public: | ||||
|  | ||||
| 	Status status = Status::INTERNAL_ERROR; | ||||
|     Fluxmap::Position position; | ||||
|     nanoseconds_t clock = 0; | ||||
| 	std::vector<nanoseconds_t> intervals; | ||||
|     nanoseconds_t headerStartTime = 0; | ||||
|     nanoseconds_t headerEndTime = 0; | ||||
|     nanoseconds_t dataStartTime = 0; | ||||
|   | ||||
| @@ -20,6 +20,7 @@ public: | ||||
|     unsigned physicalSide; | ||||
|     std::shared_ptr<FluxSource> fluxsource; | ||||
|     std::unique_ptr<Fluxmap> fluxmap; | ||||
| 	std::vector<nanoseconds_t> intervals; | ||||
|  | ||||
|     std::vector<RawRecord> rawrecords; | ||||
|     std::vector<Sector> sectors; | ||||
|   | ||||
| @@ -153,6 +153,9 @@ nanoseconds_t usbGetRotationalPeriod(void) | ||||
|  | ||||
| static int large_bulk_transfer(int ep, Bytes& bytes) | ||||
| { | ||||
|     if (bytes.size() == 0) | ||||
|         return 0; | ||||
|  | ||||
|     int len; | ||||
|     int i = libusb_bulk_transfer(device, ep, bytes.begin(), bytes.size(), &len, TIMEOUT); | ||||
|     if (i < 0) | ||||
|   | ||||
| @@ -47,8 +47,8 @@ void visualiseSectorsToFile(const SectorSet& sectors, const std::string& filenam | ||||
|  | ||||
|             auto drawArc = [&](const std::unique_ptr<Sector>& sector, nanoseconds_t start, nanoseconds_t end, const std::string& colour) | ||||
|             { | ||||
|                 start %= period*1000000; | ||||
|                 end %= period*1000000; | ||||
|                 start = fmod(start, period*1000000.0); | ||||
|                 end = fmod(end, period*1000000.0); | ||||
|                 if (end < start) | ||||
|                     end += period*1000000; | ||||
|                  | ||||
|   | ||||
| @@ -192,6 +192,7 @@ buildlibrary libbackend.a \ | ||||
|     lib/fluxsource/streamfluxsource.cc \ | ||||
|     lib/globals.cc \ | ||||
|     lib/hexdump.cc \ | ||||
| 	lib/kmedian.cc \ | ||||
|     lib/ldbs.cc \ | ||||
|     lib/reader.cc \ | ||||
|     lib/sector.cc \ | ||||
| @@ -258,6 +259,7 @@ buildsimpleprogram brother240tool \ | ||||
|     libemu.a \ | ||||
|     libfmt.a \ | ||||
|  | ||||
| runtest amiga-test          tests/amiga.cc | ||||
| runtest bitaccumulator-test tests/bitaccumulator.cc | ||||
| runtest bytes-test          tests/bytes.cc | ||||
| runtest compression-test    tests/compression.cc | ||||
| @@ -265,6 +267,7 @@ runtest dataspec-test       tests/dataspec.cc | ||||
| runtest flags-test          tests/flags.cc | ||||
| runtest fluxpattern-test    tests/fluxpattern.cc | ||||
| runtest fmmfm-test          tests/fmmfm.cc | ||||
| runtest kmedian-test        tests/kmedian.cc | ||||
| runtest kryoflux-test       tests/kryoflux.cc | ||||
| runtest ldbs-test           tests/ldbs.cc | ||||
| runtest amiga-test          tests/amiga.cc | ||||
|  | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  | ||||
| enum  | ||||
| { | ||||
|     FLUXENGINE_VERSION = 13, | ||||
|     FLUXENGINE_VERSION = 14, | ||||
|  | ||||
|     FLUXENGINE_VID = 0x1209, | ||||
|     FLUXENGINE_PID = 0x6e00, | ||||
|   | ||||
| @@ -18,6 +18,11 @@ static SettableFlag fortyTrackMode( | ||||
|     "set 48 tpi mode; only every other physical track is emitted" | ||||
| ); | ||||
|  | ||||
| static SettableFlag indexedMode( | ||||
| 	{ "--indexed", "-i" }, | ||||
| 	"align data to track boundaries" | ||||
| ); | ||||
|  | ||||
| static SettableFlag singleSided( | ||||
|     { "--single-sided", "-s" }, | ||||
|     "only emit side 0" | ||||
| @@ -45,14 +50,18 @@ static void write_le32(uint8_t dest[4], uint32_t v) | ||||
|     dest[3] = v >> 24; | ||||
| } | ||||
|  | ||||
| static void appendChecksum(uint32_t& checksum, const Bytes& bytes) | ||||
| { | ||||
| 	ByteReader br(bytes); | ||||
| 	while (!br.eof()) | ||||
| 		checksum += br.read_8(); | ||||
| } | ||||
|  | ||||
| static int strackno(int track, int side) | ||||
| { | ||||
|     if (fortyTrackMode) | ||||
|         track /= 2; | ||||
|     if (singleSided) | ||||
|         return track; | ||||
|     else | ||||
|         return (track << 1) | side; | ||||
| 	return (track << 1) | side; | ||||
| } | ||||
|  | ||||
| int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
| @@ -90,7 +99,8 @@ int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
|     fileheader.revolutions = 5; | ||||
|     fileheader.start_track = 0; | ||||
|     fileheader.end_track = maxStrack; | ||||
|     fileheader.flags = SCP_FLAG_INDEXED | (fortyTrackMode ? 0 : SCP_FLAG_96TPI); | ||||
|     fileheader.flags = (indexedMode ? SCP_FLAG_INDEXED : 0) | ||||
| 			| (fortyTrackMode ? 0 : SCP_FLAG_96TPI); | ||||
|     fileheader.cell_width = 0; | ||||
|     fileheader.heads = singleSided ? 1 : 0; | ||||
|  | ||||
| @@ -104,9 +114,15 @@ int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
|         for (int side = 0; side <= maxside; side++) | ||||
|         { | ||||
|             int strack = strackno(track, side); | ||||
|             std::cout << fmt::format("FE track {}.{}, SCP track {}: ", track, side, strack) << std::flush; | ||||
|             std::cout << fmt::format("{}.{}: ", track, side) << std::flush; | ||||
|  | ||||
|             auto fluxmap = sqlReadFlux(inputDb, track, side); | ||||
| 			if (fluxmap->bytes() == 0) | ||||
| 			{ | ||||
| 				std::cout << "missing\n"; | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
|             ScpTrack trackheader = {0}; | ||||
|             trackheader.track_id[0] = 'T'; | ||||
|             trackheader.track_id[1] = 'R'; | ||||
| @@ -117,6 +133,9 @@ int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
|             Bytes fluxdata; | ||||
|             ByteWriter fluxdataWriter(fluxdata); | ||||
|  | ||||
| 			if (indexedMode) | ||||
| 				fmr.findEvent(F_BIT_INDEX); | ||||
|  | ||||
|             int revolution = 0; | ||||
|             unsigned revTicks = 0; | ||||
|             unsigned totalTicks = 0; | ||||
| @@ -159,7 +178,7 @@ int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
|             trackdataWriter += Bytes((uint8_t*)&trackheader, sizeof(trackheader)); | ||||
|             trackdataWriter += fluxdata; | ||||
|  | ||||
|             std::cout << fmt::format("{} ms in {} bytes\n", | ||||
|             std::cout << fmt::format("{:.3f} ms in {} bytes\n", | ||||
|                 totalTicks * MS_PER_TICK, | ||||
|                 fluxdata.size()); | ||||
|         } | ||||
| @@ -167,6 +186,13 @@ int mainConvertFluxToScp(int argc, const char* argv[]) | ||||
|  | ||||
|     sqlClose(inputDb); | ||||
|      | ||||
| 	uint32_t checksum = 0; | ||||
| 	appendChecksum(checksum, | ||||
| 		Bytes((const uint8_t*) &fileheader, sizeof(fileheader)) | ||||
| 			.slice(0x10)); | ||||
| 	appendChecksum(checksum, trackdata); | ||||
| 	write_le32(fileheader.checksum, checksum); | ||||
|  | ||||
|     std::cout << "Writing output file...\n"; | ||||
|     std::ofstream of(filenames[1], std::ios::out | std::ios::binary); | ||||
|     if (!of.is_open()) | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "sector.h" | ||||
| #include "track.h" | ||||
| #include "fmt/format.h" | ||||
| #include "kmedian.h" | ||||
|  | ||||
| static FlagGroup flags { &readerFlags }; | ||||
|  | ||||
| @@ -50,6 +51,11 @@ static DoubleFlag signalLevelFactor( | ||||
|     "Clock detection signal level (min + (max-min)*factor).", | ||||
|     0.05); | ||||
|  | ||||
| static IntFlag bands( | ||||
|     { "--bands" }, | ||||
|     "Number of bands to use for k-median interval classification.", | ||||
|     3); | ||||
|  | ||||
| void setDecoderManualClockRate(double clockrate_us) | ||||
| { | ||||
|     manualClockRate.setDefaultValue(clockrate_us); | ||||
| @@ -83,54 +89,6 @@ static nanoseconds_t guessClock(const Fluxmap& fluxmap) | ||||
|     uint32_t noise_floor = min + (max-min)*noiseFloorFactor; | ||||
|     uint32_t signal_level = min + (max-min)*signalLevelFactor; | ||||
|  | ||||
|     /* Find a point solidly within the first pulse. */ | ||||
|  | ||||
|     int pulseindex = 0; | ||||
|     while (pulseindex < 256) | ||||
|     { | ||||
|         if (buckets[pulseindex] > signal_level) | ||||
|             break; | ||||
|         pulseindex++; | ||||
|     } | ||||
|     if (pulseindex == -1) | ||||
|         return 0; | ||||
|  | ||||
|     /* Find the upper and lower bounds of the pulse. */ | ||||
|  | ||||
|     int peaklo = pulseindex; | ||||
|     while (peaklo > 0) | ||||
|     { | ||||
|         if (buckets[peaklo] < noise_floor) | ||||
|             break; | ||||
|         peaklo--; | ||||
|     } | ||||
|  | ||||
|     int peakhi = pulseindex; | ||||
|     while (peakhi < 255) | ||||
|     { | ||||
|         if (buckets[peakhi] < noise_floor) | ||||
|             break; | ||||
|         peakhi++; | ||||
|     } | ||||
|  | ||||
|     /* Find the total accumulated size of the pulse. */ | ||||
|  | ||||
|     uint32_t total_size = 0; | ||||
|     for (int i = peaklo; i < peakhi; i++) | ||||
|         total_size += buckets[i]; | ||||
|  | ||||
|     /* Now find the median. */ | ||||
|  | ||||
|     uint32_t count = 0; | ||||
|     int median = peaklo; | ||||
|     while (median < peakhi) | ||||
|     { | ||||
|         count += buckets[median]; | ||||
|         if (count > (total_size/2)) | ||||
|             break; | ||||
|         median++; | ||||
|     } | ||||
|  | ||||
| 	std::cout << "\nClock detection histogram:" << std::endl; | ||||
|  | ||||
| 	bool skipping = true; | ||||
| @@ -166,16 +124,13 @@ static nanoseconds_t guessClock(const Fluxmap& fluxmap) | ||||
|  | ||||
| 	std::cout << fmt::format("Noise floor:  {}", noise_floor) << std::endl; | ||||
| 	std::cout << fmt::format("Signal level: {}", signal_level) << std::endl; | ||||
| 	std::cout << fmt::format("Peak start:   {} ({:.2f} us)", peaklo, peaklo*US_PER_TICK) << std::endl; | ||||
| 	std::cout << fmt::format("Peak end:     {} ({:.2f} us)", peakhi, peakhi*US_PER_TICK) << std::endl; | ||||
| 	std::cout << fmt::format("Median:       {} ({:.2f} us)", median, median*US_PER_TICK) << std::endl; | ||||
|  | ||||
|     /*  | ||||
|      * Okay, the median should now be a good candidate for the (or a) clock. | ||||
|      * How this maps onto the actual clock rate depends on the encoding. | ||||
|      */ | ||||
| 	std::vector<unsigned> centres = optimalKMedian(fluxmap, bands); | ||||
| 	for (int i=0; i<bands; i++) | ||||
| 		std::cout << fmt::format("Band #{}:      {} {:.2f} us\n", | ||||
| 			i, centres[i], centres[i] * US_PER_TICK); | ||||
|  | ||||
|     return median * NS_PER_TICK; | ||||
|     return centres[0] * NS_PER_TICK; | ||||
| } | ||||
|  | ||||
| int mainInspect(int argc, const char* argv[]) | ||||
| @@ -198,7 +153,7 @@ int mainInspect(int argc, const char* argv[]) | ||||
| 	nanoseconds_t clockPeriod = guessClock(*track->fluxmap); | ||||
| 	std::cout << fmt::format("{:.2f} us clock detected.", (double)clockPeriod/1000.0) << std::flush; | ||||
|  | ||||
| 	FluxmapReader fmr(*track->fluxmap); | ||||
| 	FluxmapReader fmr(*track->fluxmap, bands, false); | ||||
| 	fmr.seek(seekFlag*1000000.0); | ||||
|  | ||||
| 	if (dumpFluxFlag) | ||||
| @@ -270,7 +225,7 @@ int mainInspect(int argc, const char* argv[]) | ||||
| 			{ | ||||
| 				if (fmr.eof()) | ||||
| 					break; | ||||
| 				bool b = fmr.readRawBit(clockPeriod); | ||||
| 				bool b = fmr.readRawBit(); | ||||
| 				std::cout << (b ? 'X' : '-'); | ||||
| 			} | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ static int endSide; | ||||
|  | ||||
| static void syntax() | ||||
| { | ||||
|     std::cout << "Syntax: fluxengine convert cwftoflux <cwffile> <fluxfile>\n"; | ||||
|     std::cout << "Syntax: fluxengine convert scptoflux <scpfile> <fluxfile>\n"; | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| @@ -28,15 +28,11 @@ static void check_for_error() | ||||
|  | ||||
| static int trackno(int strack) | ||||
| { | ||||
|     if (startSide == endSide) | ||||
|         return strack; | ||||
|     return strack >> 1; | ||||
| } | ||||
|  | ||||
| static int headno(int strack) | ||||
| { | ||||
|     if (startSide == endSide) | ||||
|         return startSide; | ||||
|     return strack & 1; | ||||
| } | ||||
|  | ||||
| @@ -65,6 +61,8 @@ static void read_header() | ||||
| static void read_track(int strack) | ||||
| { | ||||
|     uint32_t offset = Bytes(header.track[strack], 4).reader().read_le32(); | ||||
| 	if (offset == 0) | ||||
| 		return; | ||||
|  | ||||
|     ScpTrack trackheader; | ||||
|     inputFile.seekg(offset, std::ios::beg); | ||||
| @@ -112,7 +110,7 @@ static void read_track(int strack) | ||||
|         inputBytes += datalength*2; | ||||
|     } | ||||
|  | ||||
|     std::cout << fmt::format(" {} ms in {} input bytes and {} output bytes\n", | ||||
|     std::cout << fmt::format(" {:.3f} ms in {} input bytes and {} output bytes\n", | ||||
|         fluxmap.duration() / 1e6, inputBytes, fluxmap.bytes()); | ||||
|     sqlWriteFlux(outputDb, trackno(strack), headno(strack), fluxmap); | ||||
| } | ||||
|   | ||||
| @@ -9,13 +9,27 @@ | ||||
|  | ||||
| static FlagGroup flags { &writerFlags, &brotherEncoderFlags }; | ||||
|  | ||||
| static int brotherFormat = 240; | ||||
| static ActionFlag preset120( | ||||
| 	{ "--brother-preset-120" }, | ||||
| 	"Write the Brother 120kB format instead of the 240kB one.", | ||||
| 	[] { | ||||
| 		setWriterDefaultInput(":c=39:h=1:s=12:b=256"); | ||||
| 		brotherFormat = 120; | ||||
| 	}); | ||||
|  | ||||
| static IntFlag bias( | ||||
| 	{ "--brother-track-bias" }, | ||||
| 	"Shift the entire format this many tracks on the disk.", | ||||
| 	0); | ||||
|  | ||||
| int mainWriteBrother(int argc, const char* argv[]) | ||||
| { | ||||
|     setWriterDefaultInput(":c=78:h=1:s=12:b=256"); | ||||
| 	setWriterDefaultDest(":d=0:t=0-77:s=0"); | ||||
|     flags.parseFlags(argc, argv); | ||||
|  | ||||
| 	BrotherEncoder encoder; | ||||
| 	BrotherEncoder encoder(brotherFormat, bias); | ||||
| 	writeDiskCommand(encoder); | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
							
								
								
									
										43
									
								
								tests/betterassert.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								tests/betterassert.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| #ifndef BETTERASSERT_H | ||||
| #define BETTERASSERT_H | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
| namespace std { | ||||
|     template <class T> | ||||
|     static std::string to_string(const std::vector<T>& vector) | ||||
|     { | ||||
|         std::stringstream s; | ||||
|         s << "vector{"; | ||||
|         bool first = true; | ||||
|         for (const T& t : vector) | ||||
|         { | ||||
|             if (!first) | ||||
|                 s << ", "; | ||||
|             first = false; | ||||
|             s << t; | ||||
|         } | ||||
|         s << "}"; | ||||
|         return s.str(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #undef assert | ||||
| #define assertEquals(got, expected) assertImpl(__FILE__, __LINE__, got, expected) | ||||
|  | ||||
| template <class T> | ||||
| static void assertImpl(const char filename[], int linenumber, T got, T expected) | ||||
| { | ||||
|     if (got != expected) | ||||
|     { | ||||
|         std::cerr << "assertion failure at " | ||||
|                   << filename << ":" << linenumber | ||||
|                   << ": got " << std::to_string(got) | ||||
|                   << ", expected " << std::to_string(expected) | ||||
|                   << std::endl; | ||||
|         abort(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| @@ -2,84 +2,49 @@ | ||||
| #include "flags.h" | ||||
| #include "fluxmap.h" | ||||
| #include "decoders/fluxmapreader.h" | ||||
| #include "betterassert.h" | ||||
| #include <sstream> | ||||
|  | ||||
| FlagGroup flags { &fluxmapReaderFlags }; | ||||
|  | ||||
| typedef std::vector<unsigned> ivector; | ||||
|  | ||||
| namespace std { | ||||
|     template <class T> | ||||
|     static std::string to_string(const std::vector<T>& vector) | ||||
|     { | ||||
|         std::stringstream s; | ||||
|         s << "vector{"; | ||||
|         bool first = true; | ||||
|         for (const T& t : vector) | ||||
|         { | ||||
|             if (!first) | ||||
|                 s << ", "; | ||||
|             first = false; | ||||
|             s << t; | ||||
|         } | ||||
|         s << "}"; | ||||
|         return s.str(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #undef assert | ||||
| #define assert(got, expected) assertImpl(__FILE__, __LINE__, got, expected) | ||||
|  | ||||
| template <class T> | ||||
| static void assertImpl(const char filename[], int linenumber, T got, T expected) | ||||
| { | ||||
|     if (got != expected) | ||||
|     { | ||||
|         std::cerr << "assertion failure at " | ||||
|                   << filename << ":" << linenumber | ||||
|                   << ": got " << std::to_string(got) | ||||
|                   << ", expected " << std::to_string(expected) | ||||
|                   << std::endl; | ||||
|         abort(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void test_patternconstruction() | ||||
| { | ||||
|     { | ||||
|         FluxPattern fp(16, 0x0003); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, ivector{ 1 }); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, ivector{ 1 }); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         FluxPattern fp(16, 0xc000); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, (ivector{ 1, 15 })); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, (ivector{ 1, 15 })); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         FluxPattern fp(16, 0x0050); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, (ivector{ 2, 5 })); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, (ivector{ 2, 5 })); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         FluxPattern fp(16, 0x0070); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, (ivector{ 1, 1, 5 })); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, (ivector{ 1, 1, 5 })); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         FluxPattern fp(16, 0x0070); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, (ivector{ 1, 1, 5 })); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, (ivector{ 1, 1, 5 })); | ||||
|     } | ||||
|  | ||||
|     { | ||||
|         FluxPattern fp(16, 0x0110); | ||||
|         assert(fp._bits, 16U); | ||||
|         assert(fp._intervals, (ivector{ 4, 5 })); | ||||
|         assertEquals(fp._bits, 16U); | ||||
|         assertEquals(fp._intervals, (ivector{ 4, 5 })); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -92,16 +57,16 @@ void test_patternmatchingwithouttrailingzeros() | ||||
|     const unsigned closematch2[] = { 110, 110, 220, 110 }; | ||||
|      | ||||
|     FluxMatch match; | ||||
|     assert(fp.matches(&matching[4], match), true); | ||||
|     assert(match.intervals, 2U); | ||||
|     assertEquals(fp.matches(&matching[4], match), true); | ||||
|     assertEquals(match.intervals, 2U); | ||||
|  | ||||
|     assert(fp.matches(¬matching[4], match), false); | ||||
|     assertEquals(fp.matches(¬matching[4], match), false); | ||||
|      | ||||
|     assert(fp.matches(&closematch1[4], match), true); | ||||
|     assert(match.intervals, 2U); | ||||
|     assertEquals(fp.matches(&closematch1[4], match), true); | ||||
|     assertEquals(match.intervals, 2U); | ||||
|  | ||||
|     assert(fp.matches(&closematch2[4], match), true); | ||||
|     assert(match.intervals, 2U); | ||||
|     assertEquals(fp.matches(&closematch2[4], match), true); | ||||
|     assertEquals(match.intervals, 2U); | ||||
| } | ||||
|  | ||||
| void test_patternmatchingwithtrailingzeros() | ||||
| @@ -113,16 +78,16 @@ void test_patternmatchingwithtrailingzeros() | ||||
|     const unsigned closematch2[] = { 110, 110, 220, 110, 220 }; | ||||
|      | ||||
|     FluxMatch match; | ||||
|     assert(fp.matches(&matching[5], match), true); | ||||
|     assert(match.intervals, 3U); | ||||
|     assertEquals(fp.matches(&matching[5], match), true); | ||||
|     assertEquals(match.intervals, 3U); | ||||
|  | ||||
|     assert(fp.matches(¬matching[5], match), false); | ||||
|     assertEquals(fp.matches(¬matching[5], match), false); | ||||
|  | ||||
|     assert(fp.matches(&closematch1[5], match), true); | ||||
|     assert(match.intervals, 3U); | ||||
|     assertEquals(fp.matches(&closematch1[5], match), true); | ||||
|     assertEquals(match.intervals, 3U); | ||||
|  | ||||
|     assert(fp.matches(&closematch2[5], match), true); | ||||
|     assert(match.intervals, 3U); | ||||
|     assertEquals(fp.matches(&closematch2[5], match), true); | ||||
|     assertEquals(match.intervals, 3U); | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) | ||||
|   | ||||
							
								
								
									
										27
									
								
								tests/kmedian.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								tests/kmedian.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #include "globals.h" | ||||
| #include <string.h> | ||||
| #include "bytes.h" | ||||
| #include "fluxmap.h" | ||||
| #include "kmedian.h" | ||||
| #include "fmt/format.h" | ||||
| #include "betterassert.h" | ||||
|  | ||||
| static void testOptimalKMedian() | ||||
| { | ||||
| 	std::vector<float> points = { 22, 36, 35, 22, 22, 23, 37, 22, 35, 47 }; | ||||
|  | ||||
| 	std::vector<float> clusters = optimalKMedian(points, 3); | ||||
|  | ||||
| 	assertEquals(clusters, | ||||
| 		(std::vector<float>{ | ||||
| 			22, 35.5, 47 | ||||
| 		}) | ||||
| 	); | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) | ||||
| { | ||||
| 	testOptimalKMedian(); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user