diff options
| -rwxr-xr-x | bootloaders/caterina_LUFA/Caterina.c | 106 | ||||
| -rw-r--r-- | bootloaders/caterina_LUFA/Caterina.hex | 386 | 
2 files changed, 300 insertions, 192 deletions
diff --git a/bootloaders/caterina_LUFA/Caterina.c b/bootloaders/caterina_LUFA/Caterina.c index dba00e3..8bd7403 100755 --- a/bootloaders/caterina_LUFA/Caterina.c +++ b/bootloaders/caterina_LUFA/Caterina.c @@ -56,6 +56,16 @@ static uint32_t CurrAddress;   */
  static bool RunBootloader = true;
 +void StartSketch()
 +{
 +	UDCON = 1;		// Detach USB
 +	UDIEN = 0;
 +	__asm__ volatile (	// Reset vector to run firmware
 +		"clr r30\n"
 +		"clr r31\n"
 +		"ijmp\n"
 +	::);
 +}
  /** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
   *  runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
 @@ -63,11 +73,21 @@ static bool RunBootloader = true;   */
  int main(void)
  {
 +	uint8_t MCUSR_state = MCUSR;	// store the reason for the reset
 +	MCUSR &= ~(1 << WDRF);			// must clear the watchdog reset flag before disabling and reenabling WDT
 +	wdt_disable();
 +	if (MCUSR_state & (1<<WDRF) && (pgm_read_word(0) != 0xFFFF)) {
 +		StartSketch();				// if the reset was caused by WDT and if a sketch is already present then run the sketch instead of the bootloader
 +	}
 +	
  	/* Setup hardware required for the bootloader */
  	SetupHardware();
  	/* Enable global interrupts so that the USB stack can function */
  	sei();
 +	
 +	DDRD |= (1<<6);	// turn on LED attached to D12 - used to track bootloader progress
 +	PORTD |= (1<<6);	
  	while (RunBootloader)
  	{
 @@ -75,6 +95,8 @@ int main(void)  		USB_USBTask();
  	}
 +	PORTD &= ~(1<<6);	// turn off LED attached to D12
 +
  	/* Disconnect from the host - USB interface will be reset later along with the AVR */
  	USB_Detach();
 @@ -109,7 +131,7 @@ void SetupHardware(void)  /** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
  ISR(TIMER1_OVF_vect, ISR_BLOCK)
  {
 -
 +	PORTD ^= (1<<6);		// toggle LED on D12
  }
  /** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
 @@ -340,6 +362,20 @@ static void WriteNextResponseByte(const uint8_t Response)  	Endpoint_Write_8(Response);
  }
 +#define STK_OK              0x10
 +#define STK_INSYNC          0x14  // ' '
 +#define CRC_EOP             0x20  // 'SPACE'
 +#define STK_GET_SYNC        0x30  // '0'
 +
 +#define STK_GET_PARAMETER   0x41  // 'A'
 +#define STK_SET_DEVICE      0x42  // 'B'
 +#define STK_SET_DEVICE_EXT  0x45  // 'E'
 +#define STK_LOAD_ADDRESS    0x55  // 'U'
 +#define STK_UNIVERSAL       0x56  // 'V'
 +#define STK_PROG_PAGE       0x64  // 'd'
 +#define STK_READ_PAGE       0x74  // 't'
 +#define STK_READ_SIGN       0x75  // 'u'
 +
  /** Task to read in AVR910 commands from the CDC data OUT endpoint, process them, perform the required actions
   *  and send the appropriate response back to the host.
   */
 @@ -355,53 +391,62 @@ void CDC_Task(void)  	/* Read in the bootloader command (first byte sent from host) */
  	uint8_t Command = FetchNextCommandByte();
 +	/*
 +	if (STK_UNIVERSAL == Command) {
 +		WriteNextResponseByte(')');
 +	} else {
 +		WriteNextResponseByte(Command);
 +	}
 +	*/
 +
 +	
  	if (Command == 'E')
  	{
  		RunBootloader = false;
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'T')
  	{
  		FetchNextCommandByte();
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if ((Command == 'L') || (Command == 'P'))
  	{
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 't')
  	{
 -		/* Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader */
 +		// Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader 
  		WriteNextResponseByte(0x44);
  		WriteNextResponseByte(0x00);
  	}
  	else if (Command == 'a')
  	{
 -		/* Indicate auto-address increment is supported */
 +		// Indicate auto-address increment is supported 
  		WriteNextResponseByte('Y');
  	}
  	else if (Command == 'A')
  	{
 -		/* Set the current address to that given by the host */
 +		// Set the current address to that given by the host 
  		CurrAddress   = (FetchNextCommandByte() << 9);
  		CurrAddress  |= (FetchNextCommandByte() << 1);
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'p')
  	{
 -		/* Indicate serial programmer back to the host */
 +		// Indicate serial programmer back to the host 
  		WriteNextResponseByte('S');
  	}
  	else if (Command == 'S')
  	{
 -		/* Write the 7-byte software identifier to the endpoint */
 +		// Write the 7-byte software identifier to the endpoint 
  		for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++)
  		  WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]);
  	}
 @@ -418,7 +463,7 @@ void CDC_Task(void)  	}
  	else if (Command == 'e')
  	{
 -		/* Clear the application section of flash */
 +		// Clear the application section of flash 
  		for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
  		{
  			boot_page_erase(CurrFlashAddress);
 @@ -427,16 +472,16 @@ void CDC_Task(void)  			boot_spm_busy_wait();
  		}
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	#if !defined(NO_LOCK_BYTE_WRITE_SUPPORT)
  	else if (Command == 'l')
  	{
 -		/* Set the lock bits to those given by the host */
 +		// Set the lock bits to those given by the host 
  		boot_lock_bits_set(FetchNextCommandByte());
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	#endif
 @@ -461,45 +506,45 @@ void CDC_Task(void)  	{
  		WriteNextResponseByte('Y');
 -		/* Send block size to the host */
 +		// Send block size to the host 
  		WriteNextResponseByte(SPM_PAGESIZE >> 8);
  		WriteNextResponseByte(SPM_PAGESIZE & 0xFF);
  	}
  	else if ((Command == 'B') || (Command == 'g'))
  	{
 -		/* Delegate the block write/read to a separate function for clarity */
 +		// Delegate the block write/read to a separate function for clarity 
  		ReadWriteMemoryBlock(Command);
  	}
  	#endif
  	#if !defined(NO_FLASH_BYTE_SUPPORT)
  	else if (Command == 'C')
  	{
 -		/* Write the high byte to the current flash page */
 +		// Write the high byte to the current flash page
  		boot_page_fill(CurrAddress, FetchNextCommandByte());
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'c')
  	{
 -		/* Write the low byte to the current flash page */
 +		// Write the low byte to the current flash page 
  		boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
 -		/* Increment the address */
 +		// Increment the address 
  		CurrAddress += 2;
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'm')
  	{
 -		/* Commit the flash page to memory */
 +		// Commit the flash page to memory
  		boot_page_write(CurrAddress);
 -		/* Wait until write operation has completed */
 +		// Wait until write operation has completed 
  		boot_spm_busy_wait();
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'R')
 @@ -517,29 +562,30 @@ void CDC_Task(void)  	#if !defined(NO_EEPROM_BYTE_SUPPORT)
  	else if (Command == 'D')
  	{
 -		/* Read the byte from the endpoint and write it to the EEPROM */
 +		// Read the byte from the endpoint and write it to the EEPROM 
  		eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
 -		/* Increment the address after use */
 +		// Increment the address after use
  		CurrAddress += 2;
 -		/* Send confirmation byte back to the host */
 +		// Send confirmation byte back to the host 
  		WriteNextResponseByte('\r');
  	}
  	else if (Command == 'd')
  	{
 -		/* Read the EEPROM byte and write it to the endpoint */
 +		// Read the EEPROM byte and write it to the endpoint 
  		WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1))));
 -		/* Increment the address after use */
 +		// Increment the address after use 
  		CurrAddress += 2;
  	}
  	#endif
  	else if (Command != 27)
  	{
 -		/* Unknown (non-sync) command, return fail code */
 +		// Unknown (non-sync) command, return fail code 
  		WriteNextResponseByte('?');
  	}
 +	
  	/* Select the IN endpoint */
  	Endpoint_SelectEndpoint(CDC_TX_EPNUM);
 diff --git a/bootloaders/caterina_LUFA/Caterina.hex b/bootloaders/caterina_LUFA/Caterina.hex index edac957..f78c001 100644 --- a/bootloaders/caterina_LUFA/Caterina.hex +++ b/bootloaders/caterina_LUFA/Caterina.hex @@ -1,173 +1,235 @@  :1070000055C000006EC000006CC000006AC00000E7
  :1070100068C0000066C0000064C0000062C00000DC
 -:1070200060C000005EC0000079C200005AC00000CD
 +:1070200060C000005EC0000053C400005AC00000F1
  :1070300058C0000056C0000054C0000052C00000FC
  :1070400050C000004EC000004CC000004AC000000C
 -:1070500048C0000046C0000044C0000042C000001C
 +:1070500052C0000046C0000044C0000042C0000012
  :1070600040C000003EC000003CC000003AC000002C
  :1070700038C0000036C0000034C0000032C000003C
  :1070800030C000002EC000002CC000002AC000004C
  :1070900028C0000026C0000024C0000022C000005C
  :1070A00020C000001EC000001CC0000011241FBE34
 -:1070B000CFEFDAE0DEBFCDBF11E0A0E0B1E0E4E168
 -:1070C000FAE702C005900D92AC38B107D9F711E08C
 -:1070D000ACE8B1E001C01D92AA39B107E1F756D181
 -:1070E00097C48ECF84E08093E9000DC08091E800C2
 -:1070F0008B778093E80003C08EB3882351F0809192
 -:10710000E80082FFF9CF8091E80085FFEFCF809102
 -:10711000F1000895982F83E08093E9008091E800C2
 -:1071200085FD0DC08091E8008E778093E80003C054
 -:107130008EB3882331F08091E80080FFF9CF9093DF
 -:10714000F10008951F93CF93DF9384E08093E900CB
 -:107150008091E80082FFC0C0C5DF853419F4109229
 -:10716000080131C0843511F4BDDF2DC08C3459F1D4
 -:10717000803549F1843721F484E4CCDF80E082C09B
 -:10718000813611F489E57EC08134F9F4ABDF182F24
 -:10719000A9DF90E0880F991FAA2797FDA095BA2F25
 -:1071A000312F330F20E0442737FD4095542F822B99
 -:1071B000932BA42BB52B80938C0190938D01A093DE
 -:1071C0008E01B0938F018DE05DC0803711F483E5AF
 -:1071D00059C0833549F4C0E0D1E089919BDF21E0BB
 -:1071E000C730D207D1F74FC0863521F481E392DF53
 -:1071F00080E348C0833731F487E88CDF85E98ADF94
 -:107200008EE140C08536B9F4E0E0F0E093E085E03F
 -:1072100090935700E89507B600FCFDCF8093570088
 -:10722000E89507B600FCFDCFE058FF4F20E7E030BF
 -:10723000F20771F7C8CF823739F4E1E0F0E089E076
 -:107240008093570084911EC0863439F4E0E0F0E06A
 -:1072500089E080935700849115C08E3439F4E3E0BF
 -:10726000F0E089E08093570084910CC0813539F4B7
 -:10727000E2E0F0E089E080935700849103C08B3115
 -:1072800011F08FE347DF83E08093E9009091E800FD
 -:107290008091E8008E778093E80095FF04C010C0CD
 -:1072A0008EB38823C9F08091E80080FFF9CF8091E8
 -:1072B000E8008E778093E80003C08EB3882361F0E6
 -:1072C0008091E80080FFF9CF84E08093E90080910D
 -:1072D000E8008B778093E800DF91CF911F910895AC
 -:1072E00090919201892F8F77813249F58091930196
 -:1072F0008032A1F0813219F5913A09F58091E800C8
 -:10730000877F8093E80089E091E067E070E0B7D183
 -:107310008091E8008B778093E8000895913279F4AA
 -:107320008091E800877F8093E80089E091E067E042
 -:1073300070E009D28091E8008E778093E80008958C
 -:1073400082E061EC42E061D083E061E842E15DD03F
 -:1073500084E060E842E159C084B7877F84BF88E158
 -:107360000FB6F89480936000109260000FBE80E02A
 -:1073700090E020E80FB6F8942093610080936100BC
 -:107380000FBE81E085BF82E085BFB0C0E5DF7894A5
 -:1073900002C0D8DE2BD3809108018823D1F78091D9
 -:1073A000E00081608093E0002CE088E190E00FB67F
 -:1073B000F894A895809360000FBE20936000FFCFE3
 -:1073C000FA01923071F0933089F0913029F480E124
 -:1073D00091E022E130E015C080E090E020E030E074
 -:1073E00010C082E291E02EE330E00BC0882329F444
 -:1073F00080E691E024E030E004C084E691E026E2FB
 -:1074000030E091838083C90108958093E9008091E1
 -:10741000EB0081608093EB001092ED006093EC0034
 -:107420004093ED008091EE00881F8827881F089503
 -:107430008091920188238CF403C08EB38823B1F02D
 -:107440008091E80082FFF9CF8091E8008B778093EC
 -:10745000E80008958EB3882349F08091E80080FF0A
 -:10746000F9CF8091E8008E778093E8000895EF923D
 -:10747000FF920F931F9345D04CD008ED10E0F80118
 -:1074800080818F77808380818068808380818F7DF9
 -:10749000808319BC1EBA1092900180EEE82EF12C68
 -:1074A000F70180818B7F8083F801808181608083F8
 -:1074B00080E060E042E0A9DFE1EEF0E080818E7FD5
 -:1074C0008083E2EEF0E0808181608083808188604B
 -:1074D0008083F70180818E7F8083F80180818061C5
 -:1074E00080831F910F91FF90EF900895E7EDF0E0FA
 -:1074F0008081816080838AE482BF81E080939101F2
 -:10750000B6CFE8EDF0E080818E7F80831092E200BC
 -:1075100008951092DA001092E10008951F920F92E0
 -:107520000FB60F9211242F933F934F935F936F9356
 -:107530007F938F939F93AF93BF93EF93FF9380912C
 -:10754000DA0080FF1BC08091D80080FF17C08091B7
 -:10755000DA008E7F8093DA008091D90080FF0BC023
 -:1075600080E189BD82E189BD09B400FEFDCF81E0E3
 -:107570008EBB3BD203C019BC1EBA37D28091E1004A
 -:1075800080FF17C08091E20080FF13C08091E2006D
 -:107590008E7F8093E2008091E20080618093E20020
 -:1075A0008091D80080628093D80019BC85E08EBBA2
 -:1075B0001CD28091E10084FF2CC08091E20084FF06
 -:1075C00028C080E189BD82E189BD09B400FEFDCFFC
 -:1075D0008091D8008F7D8093D8008091E1008F7ECC
 -:1075E0008093E1008091E2008F7E8093E2008091A1
 -:1075F000E20081608093E20080919001882331F461
 -:107600008091E30087FD02C081E001C084E08EBB71
 -:10761000ECD18091E10083FF21C08091E20083FFE3
 -:107620001DC08091E100877F8093E10082E08EBBE6
 -:10763000109290018091E1008E7F8093E100809113
 -:10764000E2008E7F8093E2008091E200806180936F
 -:10765000E20080E060E042E0D8DEC7D1FF91EF9128
 -:10766000BF91AF919F918F917F916F915F914F915A
 -:107670003F912F910F900FBE0F901F9018959C0176
 -:1076800040919801509199014617570718F4F90154
 -:1076900090E044C06115710511F0AB01F8CF809105
 -:1076A000E8008E778093E80040E050E0F0CF8EB3A2
 -:1076B000882309F444C0853009F443C08091E80070
 -:1076C00083FF02C081E008958091E80082FD31C00F
 -:1076D0008091E80080FF22C08091F3009091F20039
 -:1076E000782F60E0292F30E0262B372B07C08191BF
 -:1076F0008093F100415050402F5F3F4F411551059D
 -:1077000019F02830310598F390E02830310509F45C
 -:1077100091E08091E8008E778093E8004115510553
 -:1077200031F6992321F605C08EB3882341F08530C8
 -:1077300041F08091E80082FFF7CF80E0089582E079
 -:10774000089583E008959C016115710529F48091E5
 -:10775000E8008B778093E800F90126C08EB3882378
 -:1077600091F1853091F18091E80083FF02C081E0C2
 -:1077700008958091E80082FFF1CF06C08091F1006A
 -:1077800081936150704059F02091F3008091F20094
 -:10779000322F20E090E0822B932B892B79F7809178
 -:1077A000E8008B778093E80061157105B9F605C094
 -:1077B0008EB3882341F0853041F08091E80080FF4E
 -:1077C000F7CF80E0089582E0089583E008950F9355
 -:1077D0001F93DF93CF9300D0CDB7DEB7E2E9F1E09E
 -:1077E0008091F100819381E0EA39F807C9F778DDEB
 -:1077F0008091E80083FFE4C0809192019091930111
 -:10780000953009F46DC0963040F4913081F191309B
 -:1078100070F0933009F0D4C02AC0983009F4A3C0A6
 -:10782000993009F4B2C0963009F0CAC07CC08038E3
 -:1078300009F4C6C0823809F0C3C0809196018770F0
 -:107840008093E9008091EB001092E9002091E8001C
 -:10785000277F2093E80090E025E0969587952A956C
 -:10786000E1F781708093F1001092F10087C08823C6
 -:1078700019F0823009F0A4C08F71823009F0A0C0E5
 -:1078800080919401882331F520919601277009F4A5
 -:1078900097C02093E9008091EB0080FF1BC09330DC
 -:1078A00021F48091EB00806213C08091EB00806135
 -:1078B0008093EB0081E090E002C0880F991F2A9529
 -:1078C000E2F78093EA001092EA008091EB00886072
 -:1078D0008093EB001092E9008091E800877F51C00F
 -:1078E000882309F06DC0109194011F770FB7F894A9
 -:1078F0008091E800877F8093E8009ADD8091E8001E
 -:1079000080FFFCCF8091E3008078812B8093E3009F
 -:1079100080688093E300112311F482E001C083E0CA
 -:107920008EBB0FBF4DC08058823008F049C0809197
 -:1079300094019091950160919601AE014F5F5F4F68
 -:107940003FDDBC01009709F43BC08091E800877FD0
 -:107950008093E80089819A8192DE8091E8008B779C
 -:107960008093E8002DC0803859F58091E800877F2A
 -:107970008093E800809190018093F1008091E8006D
 -:107980008E778093E80054DD1BC08823C9F4909162
 -:1079900094019230A8F48091E800877F8093E800FA
 -:1079A0009093900145DD80919001882331F480917E
 -:1079B000E30087FD02C081E001C084E08EBBC0DC33
 -:1079C0008091E80083FF0AC08091EB008062809381
 -:1079D000EB008091E800877F8093E8000F900F9084
 -:1079E000CF91DF911F910F91089508951F938EB34A
 -:1079F000882361F01091E9001092E9008091E8007D
 -:107A000083FF01C0E4DE17701093E9001F91089511
 -:047A1000F894FFCF18
 -:107A14004C55464143444300010000000000000867
 -:107A24001201100102000008EB034A2001000001CA
 -:107A3400000109023E000201008032090400000135
 -:107A44000202010005240010010424020405240696
 -:107A54000001070582030800FF09040100020A006F
 -:107A6400000007050402100001070583021000014D
 -:107A74000403090426034100560052002000430079
 -:107A840044004300200042006F006F0074006C004B
 -:0C7A94006F0061006400650072000000DB
 +:1070B000CFEFDAE0DEBFCDBF11E0A0E0B1E0E4EF5A
 +:1070C000FDE702C005900D92AC38B107D9F711E089
 +:1070D000ACE8B1E001C01D92AA39B107E1F718D3BD
 +:1070E00087C68ECF81E08093E0001092E200EE2709
 +:1070F000FF27099408951F920F920FB60F92112443
 +:107100008F939F938BB190E489278BB99F918F9137
 +:107110000F900FBE0F901F90189584E08093E900A8
 +:107120000DC08091E8008B778093E80003C08EB398
 +:10713000882351F08091E80082FFF9CF8091E80028
 +:1071400085FFEFCF8091F1000895982F83E0809321
 +:10715000E9008091E80085FD0DC08091E8008E7700
 +:107160008093E80003C08EB3882331F08091E8005B
 +:1071700080FFF9CF9093F10008954F925F926F9244
 +:107180007F928F929F92AF92BF92CF92DF92EF92B7
 +:10719000FF920F931F93CF93DF9384E08093E900D6
 +:1071A0008091E80082FF45C2B8DF182F853419F4BA
 +:1071B0001092080103C0843519F4AFDF8DE00FC2CF
 +:1071C0008C34E1F38035D1F3843721F484E4BDDFDE
 +:1071D00080E005C2813611F489E501C28134B1F441
 +:1071E0009CDF182F9ADF90E0880F991FAA2797FD40
 +:1071F000A095BA2F312F330F20E0442737FD40955B
 +:10720000542F822B932BA42BB52BBAC1803711F4AA
 +:1072100083E5E5C1833549F4C0E0D1E0899195DF8C
 +:1072200021E0C730D207D1F7DBC1863521F481E3F5
 +:107230008CDF80E3D4C1833731F487E886DF85E9CA
 +:1072400084DF8EE1CCC18536B9F4E0E0F0E093E074
 +:1072500085E090935700E89507B600FCFDCF80933A
 +:107260005700E89507B600FCFDCFE058FF4FA0E7B8
 +:10727000E030FA0771F7A2CF8C3651F44EDF8095DB
 +:1072800099E0E1E0F0E0082E90935700E89596CF62
 +:10729000823739F4E1E0F0E089E08093570084918F
 +:1072A0009EC1863439F4E0E0F0E089E08093570035
 +:1072B000849195C18E3439F4E3E0F0E089E0809365
 +:1072C000570084918CC1813539F4E2E0F0E089E027
 +:1072D00080935700849183C1823631F489E535DF8C
 +:1072E00080E033DF80E87BC1823419F0873609F013
 +:1072F000DBC013DF082F11DFF82E0FDF682E855457
 +:10730000823008F06BC1902F80E0CF2DD0E0C82BE9
 +:10731000D92B173609F04BC081E180935700E895CF
 +:10732000DD24CC24C3943FC0E0908C01F0908D010B
 +:1073300000918E0110918F01B6E46B16D9F4ED2DFA
 +:10734000F0E0EE29FF29E4918E2FFFDEDD2081F0B1
 +:1073500082E090E0A0E0B0E0E80EF91E0A1F1B1FDB
 +:10736000E0928C01F0928D0100938E0110938F01B9
 +:10737000DC2418C0D801C701B695A79597958795C5
 +:1073800021D5E3DE82E090E0A0E0B0E0E80EF91E57
 +:107390000A1F1B1FE0928C01F0928D0100938E0159
 +:1073A00010938F012197209709F0BECF19C18090CB
 +:1073B0008C0190908D01A0908E01B0908F0196E489
 +:1073C000691609F05DC083E0F40180935700E895E9
 +:1073D00007B600FCFDCF54C0F6E46F1661F57720C8
 +:1073E00031F1E0908C01F0908D0100918E011091AF
 +:1073F0008F0193DED82ECC24852D90E08C299D29F9
 +:10740000F7010C0140925700E895112482E090E0CA
 +:10741000A0E0B0E0E80EF91E0A1F1B1FE0928C01ED
 +:10742000F0928D0100938E0110938F0102C075DEE2
 +:10743000582E742423C0E0908C01F0908D010091AF
 +:107440008E0110918F0116950795F794E79465DEEC
 +:10745000682FC701BFD480918C0190918D01A091BC
 +:107460008E01B0918F010296A11DB11D80938C01F8
 +:1074700090938D01A0938E01B0938F01219704C04A
 +:107480005524772444244394209709F0A5CF96E40B
 +:10749000691609F093CE85E0F40180935700E895D2
 +:1074A00007B600FCFDCF8ACE833471F400918C01C5
 +:1074B00010918D0132DE90E021E0F8010C01209363
 +:1074C0005700E89511247ACE833619F5E0908C01A7
 +:1074D000F0908D0100918E0110918F011EDEF70159
 +:1074E000E16090E021E00C0120935700E895112421
 +:1074F00082E090E0A0E0B0E0E80EF91E0A1F1B1F3A
 +:10750000E0928C01F0928D0100938E0110938F0117
 +:1075100055CE8D3661F4E0918C01F0918D0185E0BE
 +:1075200080935700E89507B600FCFDCF47CE823523
 +:1075300051F4E0918C01F0918D0105911491812F0E
 +:1075400004DE802F4CC0843421F5E0908C01F09053
 +:107550008D0100918E0110918F0116950795F7947A
 +:10756000E794DBDD682FC70135D480918C019091C1
 +:107570008D01A0918E01B0918F010296A11DB11DC8
 +:1075800080938C0190938D01A0938E01B0938F0115
 +:1075900015CE843609F5E0908C01F0908D010091B4
 +:1075A0008E0110918F01D801C701B695A7959795C7
 +:1075B000879508D4CADD82E090E0A0E0B0E0E80E54
 +:1075C000F91E0A1F1B1FE0928C01F0928D0100939F
 +:1075D0008E0110938F0104C08B3111F08FE3B5DD64
 +:1075E00083E08093E9009091E8008091E8008E7735
 +:1075F0008093E80095FF04C010C08EB38823C9F0C3
 +:107600008091E80080FFF9CF8091E8008E77809329
 +:10761000E80003C08EB3882361F08091E80080FF0A
 +:10762000F9CF84E08093E9008091E8008B77809324
 +:10763000E800DF91CF911F910F91FF90EF90DF90C5
 +:10764000CF90BF90AF909F908F907F906F905F9002
 +:107650004F90089590919201892F8F77813249F54B
 +:10766000809193018032A1F0813219F5913A09F5A8
 +:107670008091E800877F8093E80089E091E067E0EF
 +:1076800070E0D7D18091E8008B778093E80008956F
 +:10769000913279F48091E800877F8093E80089E057
 +:1076A00091E067E070E029D28091E8008E778093C6
 +:1076B000E800089582E061EC42E081D083E061E877
 +:1076C00042E17DD084E060E842E179C01F9384B755
 +:1076D000877F84BF88E10FB6F89480936000109292
 +:1076E00060000FBE80E090E020E80FB6F894209391
 +:1076F0006100809361000FBE11E015BF82E085BF7D
 +:10770000CFD010936F0083E0809381001F91089584
 +:1077100084B794B7977F94BF98E10FB6F89490938D
 +:107720006000109260000FBE83FF08C0E0E0F0E050
 +:10773000859194918F5F9F4F09F0D4DCC7DF7894D7
 +:10774000569A02C01ADD2CD3809108018823D1F704
 +:107750005E988091E00081608093E0002CE088E1F9
 +:1077600090E00FB6F894A895809360000FBE209328
 +:107770006000FFCFFA01923071F0933089F09130C0
 +:1077800029F480E191E022E130E015C080E090E052
 +:1077900020E030E010C082E291E02EE330E00BC048
 +:1077A000882329F480E691E024E030E004C084E6F8
 +:1077B00091E026E230E091838083C90108958093AF
 +:1077C000E9008091EB0081608093EB001092ED0066
 +:1077D0006093EC004093ED008091EE00881F8827B5
 +:1077E000881F08958091920188238CF403C08EB382
 +:1077F0008823B1F08091E80082FFF9CF8091E80002
 +:107800008B778093E80008958EB3882349F08091A8
 +:10781000E80080FFF9CF8091E8008E778093E80040
 +:107820000895EF92FF920F931F9345D04CD008ED2F
 +:1078300010E0F80180818F77808380818068808369
 +:1078400080818F7D808319BC1EBA1092900180EEDA
 +:10785000E82EF12CF70180818B7F8083F8018081F5
 +:107860008160808380E060E042E0A9DFE1EEF0E04B
 +:1078700080818E7F8083E2EEF0E080818160808372
 +:10788000808188608083F70180818E7F8083F8010A
 +:107890008081806180831F910F91FF90EF90089508
 +:1078A000E7EDF0E08081816080838AE482BF81E03F
 +:1078B00080939101B6CFE8EDF0E080818E7F8083E8
 +:1078C0001092E20008951092DA001092E1000895FB
 +:1078D0001F920F920FB60F9211242F933F934F9345
 +:1078E0005F936F937F938F939F93AF93BF93EF9328
 +:1078F000FF938091DA0080FF1BC08091D80080FF49
 +:1079000017C08091DA008E7F8093DA008091D900D1
 +:1079100080FF0BC080E189BD82E189BD09B400FE12
 +:10792000FDCF81E08EBB3BD203C019BC1EBA37D25B
 +:107930008091E10080FF17C08091E20080FF13C0BA
 +:107940008091E2008E7F8093E2008091E20080616E
 +:107950008093E2008091D80080628093D80019BCA7
 +:1079600085E08EBB1CD28091E10084FF2CC0809109
 +:10797000E20084FF28C080E189BD82E189BD09B4AD
 +:1079800000FEFDCF8091D8008F7D8093D80080913C
 +:10799000E1008F7E8093E1008091E2008F7E8093F2
 +:1079A000E2008091E20081608093E200809190018A
 +:1079B000882331F48091E30087FD02C081E001C09B
 +:1079C00084E08EBBECD18091E10083FF21C08091E7
 +:1079D000E20083FF1DC08091E100877F8093E1007A
 +:1079E00082E08EBB109290018091E1008E7F8093A7
 +:1079F000E1008091E2008E7F8093E2008091E200BE
 +:107A000080618093E20080E060E042E0D8DEC7D190
 +:107A1000FF91EF91BF91AF919F918F917F916F9166
 +:107A20005F914F913F912F910F900FBE0F901F903C
 +:107A300018959C014091980150919901461757075C
 +:107A400018F4F90190E044C06115710511F0AB0123
 +:107A5000F8CF8091E8008E778093E80040E050E016
 +:107A6000F0CF8EB3882309F444C0853009F443C0B5
 +:107A70008091E80083FF02C081E008958091E800D2
 +:107A800082FD31C08091E80080FF22C08091F30028
 +:107A90009091F200782F60E0292F30E0262B372BD1
 +:107AA00007C081918093F100415050402F5F3F4FBC
 +:107AB0004115510519F02830310598F390E0283030
 +:107AC000310509F491E08091E8008E778093E80019
 +:107AD0004115510531F6992321F605C08EB388234F
 +:107AE00041F0853041F08091E80082FFF7CF80E0DF
 +:107AF000089582E0089583E008959C016115710561
 +:107B000029F48091E8008B778093E800F90126C082
 +:107B10008EB3882391F1853091F18091E80083FF45
 +:107B200002C081E008958091E80082FFF1CF06C095
 +:107B30008091F10081936150704059F02091F300E1
 +:107B40008091F200322F20E090E0822B932B892B42
 +:107B500079F78091E8008B778093E80061157105D3
 +:107B6000B9F605C08EB3882341F0853041F080918D
 +:107B7000E80080FFF7CF80E0089582E0089583E079
 +:107B800008950F931F93DF93CF9300D0CDB7DEB747
 +:107B9000E2E9F1E08091F100819381E0EA39F807B0
 +:107BA000C9F758DD8091E80083FFE4C0809192011D
 +:107BB00090919301953009F46DC0963040F4913066
 +:107BC00081F1913070F0933009F0D4C02AC0983020
 +:107BD00009F4A3C0993009F4B2C0963009F0CAC0C4
 +:107BE0007CC0803809F4C6C0823809F0C3C08091D7
 +:107BF000960187708093E9008091EB001092E90074
 +:107C00002091E800277F2093E80090E025E09695FA
 +:107C100087952A95E1F781708093F1001092F10029
 +:107C200087C0882319F0823009F0A4C08F71823098
 +:107C300009F0A0C080919401882331F5209196012C
 +:107C4000277009F497C02093E9008091EB0080FF32
 +:107C50001BC0933021F48091EB00806213C08091AF
 +:107C6000EB0080618093EB0081E090E002C0880F20
 +:107C7000991F2A95E2F78093EA001092EA0080911A
 +:107C8000EB0088608093EB001092E9008091E8009F
 +:107C9000877F51C0882309F06DC0109194011F7730
 +:107CA0000FB7F8948091E800877F8093E8009ADD11
 +:107CB0008091E80080FFFCCF8091E3008078812BE9
 +:107CC0008093E30080688093E300112311F482E045
 +:107CD00001C083E08EBB0FBF4DC08058823008F0DA
 +:107CE00049C0809194019091950160919601AE01F7
 +:107CF0004F5F5F4F3FDDBC01009709F43BC08091AF
 +:107D0000E800877F8093E80089819A8192DE8091E4
 +:107D1000E8008B778093E8002DC0803859F580917A
 +:107D2000E800877F8093E800809190018093F100C4
 +:107D30008091E8008E778093E80054DD1BC0882393
 +:107D4000C9F4909194019230A8F48091E800877F63
 +:107D50008093E8009093900145DD80919001882305
 +:107D600031F48091E30087FD02C081E001C084E02E
 +:107D70008EBBA0DC8091E80083FF0AC08091EB00FD
 +:107D800080628093EB008091E800877F8093E80019
 +:107D90000F900F90CF91DF911F910F91089508954B
 +:107DA0001F938EB3882361F01091E9001092E900CF
 +:107DB0008091E80083FF01C0E4DE17701093E900B2
 +:107DC0001F910895F999FECF92BD81BDF89A992728
 +:107DD00080B50895262FF999FECF1FBA92BD81BDB7
 +:107DE00020BD0FB6F894FA9AF99A0FBE019608953D
 +:047DF000F894FFCF35
 +:107DF4004C55464143444300010000000000000884
 +:107E04001201100102000008EB034A2001000001E6
 +:107E1400000109023E000201008032090400000151
 +:107E240002020100052400100104240204052406B2
 +:107E34000001070582030800FF09040100020A008B
 +:107E44000000070504021000010705830210000169
 +:107E54000403090426034100560052002000430095
 +:107E640044004300200042006F006F0074006C0067
 +:0C7E74006F0061006400650072000000F7
  :040000030000700089
  :00000001FF
  | 
